b1525 - Added IPv6 support
This commit is contained in:
		
							parent
							
								
									256e2370a3
								
							
						
					
					
						commit
						fdd4c7bac7
					
				
					 8 changed files with 275 additions and 197 deletions
				
			
		|  | @ -70,7 +70,8 @@ namespace SRMultiplayer | |||
|                         !assembly.GetName().Name.Contains("Logger") && !assembly.GetName().Name.Contains("Mono.") && !assembly.GetName().Name.Contains("Harmony") && | ||||
|                         !assembly.GetName().Name.Equals("SRML") && !assembly.GetName().Name.Equals("SRML.Editor") && !assembly.GetName().Name.Equals("Newtonsoft.Json") && | ||||
|                         !assembly.GetName().Name.Equals("INIFileParser") && !assembly.GetName().Name.Equals("SRMultiplayer") && !assembly.GetName().Name.Contains("Microsoft.") && | ||||
|                         !assembly.GetName().Name.Equals("SRMP") && !assembly.GetName().Name.Equals("XGamingRuntime") && !Globals.UserData.IgnoredMods.Contains(assembly.GetName().Name)) | ||||
|                         !assembly.GetName().Name.Equals("SRMP") && !assembly.GetName().Name.Equals("XGamingRuntime") && !assembly.GetName().Name.Contains("MonoMod.Utils.")  | ||||
|                         && !Globals.UserData.IgnoredMods.Contains(assembly.GetName().Name)) | ||||
|                     { | ||||
|                         mods.Add(assembly.GetName().Name); | ||||
|                     } | ||||
|  |  | |||
|  | @ -123,7 +123,7 @@ namespace Lidgren.Network | |||
| 					mutex.WaitOne(); | ||||
| 
 | ||||
| 					if (m_socket == null) | ||||
| 						m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); | ||||
| 						m_socket = new Socket(m_configuration.LocalAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); | ||||
| 
 | ||||
| 					if (reBind) | ||||
| 						m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1); | ||||
|  | @ -132,7 +132,19 @@ namespace Lidgren.Network | |||
| 					m_socket.SendBufferSize = m_configuration.SendBufferSize; | ||||
| 					m_socket.Blocking = false; | ||||
| 
 | ||||
| 					var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port); | ||||
|                     if (m_configuration.DualStack) | ||||
|                     { | ||||
|                         if (m_configuration.LocalAddress.AddressFamily != AddressFamily.InterNetworkV6) | ||||
|                         { | ||||
|                             LogWarning("Configuration specifies Dual Stack but does not use IPv6 local address; Dual stack will not work."); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             m_socket.DualMode = true; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port); | ||||
| 					m_socket.Bind(ep); | ||||
| 
 | ||||
| 					try | ||||
|  | @ -412,172 +424,175 @@ namespace Lidgren.Network | |||
| 			// update now | ||||
| 			now = NetTime.Now; | ||||
| 
 | ||||
| 			do | ||||
|             try | ||||
|             { | ||||
| 		        do | ||||
|                 { | ||||
|                     ReceiveSocketData(now); | ||||
|                 } while (m_socket.Available > 0); | ||||
|             } | ||||
|             catch (SocketException sx) | ||||
|             { | ||||
|                 switch (sx.SocketErrorCode) | ||||
|                 { | ||||
|                     case SocketError.ConnectionReset: | ||||
|                         // connection reset by peer, aka connection forcibly closed aka "ICMP port unreachable" | ||||
|                         // we should shut down the connection; but m_senderRemote seemingly cannot be trusted, so which connection should we shut down?! | ||||
|                         // So, what to do? | ||||
|                         LogWarning("ConnectionReset"); | ||||
|                         return; | ||||
| 
 | ||||
|                     case SocketError.NotConnected: | ||||
|                         // socket is unbound; try to rebind it (happens on mobile when process goes to sleep) | ||||
|                         BindSocket(true); | ||||
|                         return; | ||||
| 
 | ||||
|                     default: | ||||
|                         LogWarning("Socket exception: " + sx.ToString()); | ||||
|                         return; | ||||
|                 } | ||||
|             } | ||||
| 		} | ||||
| 
 | ||||
|         private void ReceiveSocketData(double now) | ||||
|         { | ||||
|             int bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote); | ||||
| 
 | ||||
| 			if (bytesReceived < NetConstants.HeaderByteSize) | ||||
| 				return; | ||||
| 
 | ||||
| 			//LogVerbose("Received " + bytesReceived + " bytes"); | ||||
| 
 | ||||
| 			var ipsender = (NetEndPoint)m_senderRemote; | ||||
| 
 | ||||
| 			if (m_upnp != null && now < m_upnp.m_discoveryResponseDeadline && bytesReceived > 32) | ||||
| 			{ | ||||
| 				int bytesReceived = 0; | ||||
| 				try | ||||
| 				// is this an UPnP response? | ||||
| 				string resp = System.Text.Encoding.UTF8.GetString(m_receiveBuffer, 0, bytesReceived); | ||||
| 				if (resp.Contains("upnp:rootdevice") || resp.Contains("UPnP/1.0")) | ||||
| 				{ | ||||
| 					bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote); | ||||
| 				} | ||||
| 				catch (SocketException sx) | ||||
| 				{ | ||||
| 					switch (sx.SocketErrorCode) | ||||
| 					{ | ||||
| 						case SocketError.ConnectionReset: | ||||
| 							// connection reset by peer, aka connection forcibly closed aka "ICMP port unreachable" | ||||
| 							// we should shut down the connection; but m_senderRemote seemingly cannot be trusted, so which connection should we shut down?! | ||||
| 							// So, what to do? | ||||
| 							LogWarning("ConnectionReset"); | ||||
| 							return; | ||||
| 
 | ||||
| 						case SocketError.NotConnected: | ||||
| 							// socket is unbound; try to rebind it (happens on mobile when process goes to sleep) | ||||
| 							BindSocket(true); | ||||
| 							return; | ||||
| 
 | ||||
| 						default: | ||||
| 							LogWarning("Socket exception: " + sx.ToString()); | ||||
| 							return; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if (bytesReceived < NetConstants.HeaderByteSize) | ||||
| 					return; | ||||
| 
 | ||||
| 				//LogVerbose("Received " + bytesReceived + " bytes"); | ||||
| 
 | ||||
| 				var ipsender = (NetEndPoint)m_senderRemote; | ||||
| 
 | ||||
| 				if (m_upnp != null && now < m_upnp.m_discoveryResponseDeadline && bytesReceived > 32) | ||||
| 				{ | ||||
| 					// is this an UPnP response? | ||||
| 					string resp = System.Text.Encoding.UTF8.GetString(m_receiveBuffer, 0, bytesReceived); | ||||
| 					if (resp.Contains("upnp:rootdevice") || resp.Contains("UPnP/1.0")) | ||||
| 					{ | ||||
| 						try | ||||
| 						{ | ||||
| 							resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); | ||||
| 							resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); | ||||
| 							m_upnp.ExtractServiceUrl(resp); | ||||
| 							return; | ||||
| 						} | ||||
| 						catch (Exception ex) | ||||
| 						{ | ||||
| 							LogDebug("Failed to parse UPnP response: " + ex.ToString()); | ||||
| 
 | ||||
| 							// don't try to parse this packet further | ||||
| 							return; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				NetConnection sender = null; | ||||
| 				m_connectionLookup.TryGetValue(ipsender, out sender); | ||||
| 
 | ||||
| 				// | ||||
| 				// parse packet into messages | ||||
| 				// | ||||
| 				int numMessages = 0; | ||||
| 				int numFragments = 0; | ||||
| 				int ptr = 0; | ||||
| 				while ((bytesReceived - ptr) >= NetConstants.HeaderByteSize) | ||||
| 				{ | ||||
| 					// decode header | ||||
| 					//  8 bits - NetMessageType | ||||
| 					//  1 bit  - Fragment? | ||||
| 					// 15 bits - Sequence number | ||||
| 					// 16 bits - Payload length in bits | ||||
| 
 | ||||
| 					numMessages++; | ||||
| 
 | ||||
| 					NetMessageType tp = (NetMessageType)m_receiveBuffer[ptr++]; | ||||
| 
 | ||||
| 					byte low = m_receiveBuffer[ptr++]; | ||||
| 					byte high = m_receiveBuffer[ptr++]; | ||||
| 
 | ||||
| 					bool isFragment = ((low & 1) == 1); | ||||
| 					ushort sequenceNumber = (ushort)((low >> 1) | (((int)high) << 7)); | ||||
| 
 | ||||
| 					if (isFragment) | ||||
| 						numFragments++; | ||||
| 
 | ||||
| 					ushort payloadBitLength = (ushort)(m_receiveBuffer[ptr++] | (m_receiveBuffer[ptr++] << 8)); | ||||
| 					int payloadByteLength = NetUtility.BytesToHoldBits(payloadBitLength); | ||||
| 
 | ||||
| 					if (bytesReceived - ptr < payloadByteLength) | ||||
| 					{ | ||||
| 						LogWarning("Malformed packet; stated payload length " + payloadByteLength + ", remaining bytes " + (bytesReceived - ptr)); | ||||
| 						return; | ||||
| 					} | ||||
| 
 | ||||
| 					if (tp >= NetMessageType.Unused1 && tp <= NetMessageType.Unused29) | ||||
| 					{ | ||||
| 						ThrowOrLog("Unexpected NetMessageType: " + tp); | ||||
| 						return; | ||||
| 					} | ||||
| 
 | ||||
| 					try | ||||
| 					{ | ||||
| 						if (tp >= NetMessageType.LibraryError) | ||||
| 						{ | ||||
| 							if (sender != null) | ||||
| 								sender.ReceivedLibraryMessage(tp, ptr, payloadByteLength); | ||||
| 							else | ||||
| 								ReceivedUnconnectedLibraryMessage(now, ipsender, tp, ptr, payloadByteLength); | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							if (sender == null && !m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData)) | ||||
| 								return; // dropping unconnected message since it's not enabled | ||||
| 
 | ||||
| 							NetIncomingMessage msg = CreateIncomingMessage(NetIncomingMessageType.Data, payloadByteLength); | ||||
| 							msg.m_isFragment = isFragment; | ||||
| 							msg.m_receiveTime = now; | ||||
| 							msg.m_sequenceNumber = sequenceNumber; | ||||
| 							msg.m_receivedMessageType = tp; | ||||
| 							msg.m_senderConnection = sender; | ||||
| 							msg.m_senderEndPoint = ipsender; | ||||
| 							msg.m_bitLength = payloadBitLength; | ||||
| 
 | ||||
| 							Buffer.BlockCopy(m_receiveBuffer, ptr, msg.m_data, 0, payloadByteLength); | ||||
| 							if (sender != null) | ||||
| 							{ | ||||
| 								if (tp == NetMessageType.Unconnected) | ||||
| 								{ | ||||
| 									// We're connected; but we can still send unconnected messages to this peer | ||||
| 									msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; | ||||
| 									ReleaseMessage(msg); | ||||
| 								} | ||||
| 								else | ||||
| 								{ | ||||
| 									// connected application (non-library) message | ||||
| 									sender.ReceivedMessage(msg); | ||||
| 								} | ||||
| 							} | ||||
| 							else | ||||
| 							{ | ||||
| 								// at this point we know the message type is enabled | ||||
| 								// unconnected application (non-library) message | ||||
| 								msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; | ||||
| 								ReleaseMessage(msg); | ||||
| 							} | ||||
| 						} | ||||
| 						resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); | ||||
| 						resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); | ||||
| 						m_upnp.ExtractServiceUrl(resp); | ||||
| 						return; | ||||
| 					} | ||||
| 					catch (Exception ex) | ||||
| 					{ | ||||
| 						LogError("Packet parsing error: " + ex.Message + " from " + ipsender); | ||||
| 						LogDebug("Failed to parse UPnP response: " + ex.ToString()); | ||||
| 
 | ||||
| 						// don't try to parse this packet further | ||||
| 						return; | ||||
| 					} | ||||
| 					ptr += payloadByteLength; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			NetConnection sender = null; | ||||
| 			m_connectionLookup.TryGetValue(ipsender, out sender); | ||||
| 
 | ||||
| 			// | ||||
| 			// parse packet into messages | ||||
| 			// | ||||
| 			int numMessages = 0; | ||||
| 			int numFragments = 0; | ||||
| 			int ptr = 0; | ||||
| 			while ((bytesReceived - ptr) >= NetConstants.HeaderByteSize) | ||||
| 			{ | ||||
| 				// decode header | ||||
| 				//  8 bits - NetMessageType | ||||
| 				//  1 bit  - Fragment? | ||||
| 				// 15 bits - Sequence number | ||||
| 				// 16 bits - Payload length in bits | ||||
| 
 | ||||
| 				numMessages++; | ||||
| 
 | ||||
| 				NetMessageType tp = (NetMessageType)m_receiveBuffer[ptr++]; | ||||
| 
 | ||||
| 				byte low = m_receiveBuffer[ptr++]; | ||||
| 				byte high = m_receiveBuffer[ptr++]; | ||||
| 
 | ||||
| 				bool isFragment = ((low & 1) == 1); | ||||
| 				ushort sequenceNumber = (ushort)((low >> 1) | (((int)high) << 7)); | ||||
| 
 | ||||
| 				if (isFragment) | ||||
| 					numFragments++; | ||||
| 
 | ||||
| 				ushort payloadBitLength = (ushort)(m_receiveBuffer[ptr++] | (m_receiveBuffer[ptr++] << 8)); | ||||
| 				int payloadByteLength = NetUtility.BytesToHoldBits(payloadBitLength); | ||||
| 
 | ||||
| 				if (bytesReceived - ptr < payloadByteLength) | ||||
| 				{ | ||||
| 					LogWarning("Malformed packet; stated payload length " + payloadByteLength + ", remaining bytes " + (bytesReceived - ptr)); | ||||
| 					return; | ||||
| 				} | ||||
| 
 | ||||
| 				m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); | ||||
| 				if (sender != null) | ||||
| 					sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); | ||||
| 				if (tp >= NetMessageType.Unused1 && tp <= NetMessageType.Unused29) | ||||
| 				{ | ||||
| 					ThrowOrLog("Unexpected NetMessageType: " + tp); | ||||
| 					return; | ||||
| 				} | ||||
| 
 | ||||
| 			} while (m_socket.Available > 0); | ||||
| 		} | ||||
| 				try | ||||
| 				{ | ||||
| 					if (tp >= NetMessageType.LibraryError) | ||||
| 					{ | ||||
| 						if (sender != null) | ||||
| 							sender.ReceivedLibraryMessage(tp, ptr, payloadByteLength); | ||||
| 						else | ||||
| 							ReceivedUnconnectedLibraryMessage(now, ipsender, tp, ptr, payloadByteLength); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						if (sender == null && !m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData)) | ||||
| 							return; // dropping unconnected message since it's not enabled | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 						NetIncomingMessage msg = CreateIncomingMessage(NetIncomingMessageType.Data, payloadByteLength); | ||||
| 						msg.m_isFragment = isFragment; | ||||
| 						msg.m_receiveTime = now; | ||||
| 						msg.m_sequenceNumber = sequenceNumber; | ||||
| 						msg.m_receivedMessageType = tp; | ||||
| 						msg.m_senderConnection = sender; | ||||
| 						msg.m_senderEndPoint = ipsender; | ||||
| 						msg.m_bitLength = payloadBitLength; | ||||
| 
 | ||||
| 						Buffer.BlockCopy(m_receiveBuffer, ptr, msg.m_data, 0, payloadByteLength); | ||||
| 						if (sender != null) | ||||
| 						{ | ||||
| 							if (tp == NetMessageType.Unconnected) | ||||
| 							{ | ||||
| 								// We're connected; but we can still send unconnected messages to this peer | ||||
| 								msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; | ||||
| 								ReleaseMessage(msg); | ||||
| 							} | ||||
| 							else | ||||
| 							{ | ||||
| 								// connected application (non-library) message | ||||
| 								sender.ReceivedMessage(msg); | ||||
| 							} | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							// at this point we know the message type is enabled | ||||
| 							// unconnected application (non-library) message | ||||
| 							msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; | ||||
| 							ReleaseMessage(msg); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				catch (Exception ex) | ||||
| 				{ | ||||
| 					LogError("Packet parsing error: " + ex.Message + " from " + ipsender); | ||||
| 				} | ||||
| 				ptr += payloadByteLength; | ||||
| 			} | ||||
| 
 | ||||
| 			m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); | ||||
| 			if (sender != null) | ||||
| 				sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| 		/// If NetPeerConfiguration.AutoFlushSendQueue() is false; you need to call this to send all messages queued using SendMessage() | ||||
| 		/// </summary> | ||||
| 		public void FlushSendQueue() | ||||
|  | @ -686,7 +701,7 @@ namespace Lidgren.Network | |||
| 				case NetMessageType.Connect: | ||||
| 					if (m_configuration.AcceptIncomingConnections == false) | ||||
| 					{ | ||||
| 						LogWarning(m_configuration.AppIdentifier + " Received Connect, but we're not accepting incoming connections!"); | ||||
| 						LogWarning("Received Connect, but we're not accepting incoming connections!"); | ||||
| 						return; | ||||
| 					} | ||||
| 					// handle connect | ||||
|  |  | |||
|  | @ -132,6 +132,9 @@ namespace Lidgren.Network | |||
| 			catch { } | ||||
| 		} | ||||
| 
 | ||||
|         //Avoids allocation on mapping to IPv6 | ||||
|         private IPEndPoint targetCopy = new IPEndPoint(IPAddress.Any, 0); | ||||
| 
 | ||||
| 		internal bool ActuallySendPacket(byte[] data, int numBytes, NetEndPoint target, out bool connectionReset) | ||||
| 		{ | ||||
| 			connectionReset = false; | ||||
|  | @ -140,17 +143,25 @@ namespace Lidgren.Network | |||
| 			{ | ||||
| 				ba = NetUtility.GetCachedBroadcastAddress(); | ||||
| 
 | ||||
| 				// TODO: refactor this check outta here | ||||
| 				if (target.Address.Equals(ba)) | ||||
| 				{ | ||||
| 					// Some networks do not allow  | ||||
| 					// a global broadcast so we use the BroadcastAddress from the configuration | ||||
| 					// this can be resolved to a local broadcast addresss e.g 192.168.x.255                     | ||||
| 					target.Address = m_configuration.BroadcastAddress; | ||||
| 					m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); | ||||
| 				} | ||||
|                 // TODO: refactor this check outta here | ||||
|                 if (target.Address.Equals(ba)) | ||||
|                 { | ||||
|                     // Some networks do not allow  | ||||
|                     // a global broadcast so we use the BroadcastAddress from the configuration | ||||
|                     // this can be resolved to a local broadcast addresss e.g 192.168.x.255                     | ||||
|                     targetCopy.Address = m_configuration.BroadcastAddress; | ||||
|                     targetCopy.Port = target.Port; | ||||
|                     m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); | ||||
|                 } | ||||
|                 else if(m_configuration.DualStack && m_configuration.LocalAddress.AddressFamily == AddressFamily.InterNetworkV6) | ||||
|                     NetUtility.CopyEndpoint(target, targetCopy); //Maps to IPv6 for Dual Mode | ||||
|                 else | ||||
|                 { | ||||
| 	                targetCopy.Port = target.Port; | ||||
| 	                targetCopy.Address = target.Address; | ||||
|                 } | ||||
| 
 | ||||
| 				int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, target); | ||||
|                 int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, targetCopy); | ||||
| 				if (numBytes != bytesSent) | ||||
| 					LogWarning("Failed to send the full " + numBytes + "; only " + bytesSent + " bytes sent in packet!"); | ||||
| 
 | ||||
|  | @ -178,7 +189,7 @@ namespace Lidgren.Network | |||
| 			} | ||||
| 			finally | ||||
| 			{ | ||||
| 				if (target.Address == ba) | ||||
| 				if (target.Address.Equals(ba)) | ||||
| 					m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); | ||||
| 			} | ||||
| 			return true; | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| using System.Threading; | ||||
| using System.Collections.Generic; | ||||
| using System.Net; | ||||
| 
 | ||||
| using System.Net.Sockets; | ||||
| #if !__NOIPENDPOINT__ | ||||
| using NetEndPoint = System.Net.IPEndPoint; | ||||
| #endif | ||||
|  | @ -32,8 +32,8 @@ namespace Lidgren.Network | |||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Signalling event which can be waited on to determine when a message is queued for reading. | ||||
| 		/// Note that there is no guarantee that after the event is signaled the blocked thread will  | ||||
| 		/// find the message in the queue. Other user created threads could be preempted and dequeue  | ||||
| 		/// Note that there is no guarantee that after the event is signaled the blocked thread will | ||||
| 		/// find the message in the queue. Other user created threads could be preempted and dequeue | ||||
| 		/// the message before the waiting thread wakes up. | ||||
| 		/// </summary> | ||||
| 		public AutoResetEvent MessageReceivedEvent | ||||
|  | @ -121,9 +121,16 @@ namespace Lidgren.Network | |||
| 			m_connections = new List<NetConnection>(); | ||||
| 			m_connectionLookup = new Dictionary<NetEndPoint, NetConnection>(); | ||||
| 			m_handshakes = new Dictionary<NetEndPoint, NetConnection>(); | ||||
| 			m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.Any, 0); | ||||
|             if (m_configuration.LocalAddress.AddressFamily == AddressFamily.InterNetworkV6) | ||||
|             { | ||||
|                 m_senderRemote = (EndPoint)new IPEndPoint(IPAddress.IPv6Any, 0); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_senderRemote = (EndPoint)new IPEndPoint(IPAddress.Any, 0); | ||||
|             } | ||||
| 			m_status = NetPeerStatus.NotRunning; | ||||
| 			m_receivedFragmentGroups = new Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>>();	 | ||||
| 			m_receivedFragmentGroups = new Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>>(); | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
|  | @ -148,7 +155,7 @@ namespace Lidgren.Network | |||
| 			} | ||||
| 
 | ||||
| 			InitializeNetwork(); | ||||
| 			 | ||||
| 
 | ||||
| 			// start network thread | ||||
| 			m_networkThread = new Thread(new ThreadStart(NetworkLoop)); | ||||
| 			m_networkThread.Name = m_configuration.NetworkThreadName; | ||||
|  | @ -183,7 +190,7 @@ namespace Lidgren.Network | |||
| 	        public NetIncomingMessage WaitMessage(int maxMillis) | ||||
| 	        { | ||||
| 	            NetIncomingMessage msg = ReadMessage(); | ||||
| 	 | ||||
| 
 | ||||
| 	            while (msg == null) | ||||
| 	            { | ||||
| 	                // This could return true... | ||||
|  | @ -191,11 +198,11 @@ namespace Lidgren.Network | |||
| 	                { | ||||
| 	                    return null; | ||||
| 	                } | ||||
| 	 | ||||
| 
 | ||||
| 	                // ... while this will still returns null. That's why we need to cycle. | ||||
| 	                msg = ReadMessage(); | ||||
| 	            } | ||||
| 	 | ||||
| 
 | ||||
| 	            return msg; | ||||
|         	} | ||||
| 
 | ||||
|  | @ -215,7 +222,7 @@ namespace Lidgren.Network | |||
| 			} | ||||
| 			return retval; | ||||
| 		} | ||||
| 		 | ||||
| 
 | ||||
|         	/// <summary> | ||||
| 	        /// Reads a pending message from any connection, if any. | ||||
| 	        /// Returns true if message was read, otherwise false. | ||||
|  | @ -303,6 +310,8 @@ namespace Lidgren.Network | |||
| 		{ | ||||
| 			if (remoteEndPoint == null) | ||||
| 				throw new ArgumentNullException("remoteEndPoint"); | ||||
|             if(m_configuration.DualStack) | ||||
|                 remoteEndPoint = NetUtility.MapToIPv6(remoteEndPoint); | ||||
| 
 | ||||
| 			lock (m_connections) | ||||
| 			{ | ||||
|  |  | |||
|  | @ -35,12 +35,12 @@ namespace Lidgren.Network | |||
| 		//  -4 bytes to be on the safe side and align to 8-byte boundary | ||||
| 		// Total 1408 bytes | ||||
| 		// Note that lidgren headers (5 bytes) are not included here; since it's part of the "mtu payload" | ||||
| 		 | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Default MTU value in bytes | ||||
| 		/// </summary> | ||||
| 		public const int kDefaultMTU = 1408; | ||||
| 		 | ||||
| 
 | ||||
| 		private const string c_isLockedMessage = "You may not modify the NetPeerConfiguration after it has been used to initialize a NetPeer"; | ||||
| 
 | ||||
| 		private bool m_isLocked; | ||||
|  | @ -48,6 +48,8 @@ namespace Lidgren.Network | |||
| 		private string m_networkThreadName; | ||||
| 		private IPAddress m_localAddress; | ||||
| 		private IPAddress m_broadcastAddress; | ||||
|         private bool m_dualStack; | ||||
| 
 | ||||
| 		internal bool m_acceptIncomingConnections; | ||||
| 		internal int m_maximumConnections; | ||||
| 		internal int m_defaultOutgoingMessageCapacity; | ||||
|  | @ -341,10 +343,26 @@ namespace Lidgren.Network | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Gets or sets the local broadcast address to use when broadcasting | ||||
| 		/// </summary> | ||||
| 		public IPAddress BroadcastAddress | ||||
|         /// <summary> | ||||
|         /// Gets or sets a value indicating whether the library should use IPv6 dual stack mode. | ||||
|         /// If you enable this you should make sure that the <see cref="LocalAddress"/> is an IPv6 address. | ||||
|         /// Cannot be changed once NetPeer is initialized. | ||||
|         /// </summary> | ||||
|         public bool DualStack | ||||
|         { | ||||
|             get { return m_dualStack;  } | ||||
|             set | ||||
|             { | ||||
|                 if (m_isLocked) | ||||
|                     throw new NetException(c_isLockedMessage); | ||||
|                 m_dualStack = value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets or sets the local broadcast address to use when broadcasting | ||||
|         /// </summary> | ||||
|         public IPAddress BroadcastAddress | ||||
| 		{ | ||||
| 			get { return m_broadcastAddress; } | ||||
| 			set | ||||
|  |  | |||
|  | @ -98,7 +98,7 @@ namespace Lidgren.Network | |||
| 			NetAddress ipAddress = null; | ||||
| 			if (NetAddress.TryParse(ipOrHost, out ipAddress)) | ||||
| 			{ | ||||
| 				if (ipAddress.AddressFamily == AddressFamily.InterNetwork) | ||||
| 				if (ipAddress.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6) | ||||
| 				{ | ||||
| 					callback(ipAddress); | ||||
| 					return; | ||||
|  | @ -139,7 +139,7 @@ namespace Lidgren.Network | |||
| 					// check each entry for a valid IP address | ||||
| 					foreach (var ipCurrent in entry.AddressList) | ||||
| 					{ | ||||
| 						if (ipCurrent.AddressFamily == AddressFamily.InterNetwork) | ||||
| 						if (ipCurrent.AddressFamily == AddressFamily.InterNetwork || ipCurrent.AddressFamily == AddressFamily.InterNetworkV6) | ||||
| 						{ | ||||
| 							callback(ipCurrent); | ||||
| 							return; | ||||
|  | @ -163,7 +163,7 @@ namespace Lidgren.Network | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
|         /// <summary> | ||||
| 		/// Get IPv4 address from notation (xxx.xxx.xxx.xxx) or hostname | ||||
| 		/// </summary> | ||||
| 		public static NetAddress Resolve(string ipOrHost) | ||||
|  | @ -176,9 +176,9 @@ namespace Lidgren.Network | |||
| 			NetAddress ipAddress = null; | ||||
| 			if (NetAddress.TryParse(ipOrHost, out ipAddress)) | ||||
| 			{ | ||||
| 				if (ipAddress.AddressFamily == AddressFamily.InterNetwork) | ||||
| 				if (ipAddress.AddressFamily == AddressFamily.InterNetwork || ipAddress.AddressFamily == AddressFamily.InterNetworkV6) | ||||
| 					return ipAddress; | ||||
| 				throw new ArgumentException("This method will not currently resolve other than ipv4 addresses"); | ||||
| 				throw new ArgumentException("This method will not currently resolve other than IPv4 or IPv6 addresses"); | ||||
| 			} | ||||
| 
 | ||||
| 			// ok must be a host name | ||||
|  | @ -189,7 +189,7 @@ namespace Lidgren.Network | |||
| 					return null; | ||||
| 				foreach (var address in addresses) | ||||
| 				{ | ||||
| 					if (address.AddressFamily == AddressFamily.InterNetwork) | ||||
| 					if (address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6) | ||||
| 						return address; | ||||
| 				} | ||||
| 				return null; | ||||
|  | @ -240,7 +240,7 @@ namespace Lidgren.Network | |||
| 			} | ||||
| 			return new string(c); | ||||
| 		} | ||||
| 	 | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Returns true if the endpoint supplied is on the same subnet as this host | ||||
| 		/// </summary> | ||||
|  | @ -465,5 +465,29 @@ namespace Lidgren.Network | |||
| 			// this is defined in the platform specific files | ||||
| 			return ComputeSHAHash(bytes, 0, bytes.Length); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Copies from <paramref name="src"/> to <paramref name="dst"/>. Maps to an IPv6 address | ||||
|         /// </summary> | ||||
|         /// <param name="src">Source.</param> | ||||
|         /// <param name="dst">Destination.</param> | ||||
|         internal static void CopyEndpoint(IPEndPoint src, IPEndPoint dst) | ||||
|         { | ||||
|             dst.Port = src.Port; | ||||
|             if (src.AddressFamily == AddressFamily.InterNetwork) | ||||
|                 dst.Address = src.Address.MapToIPv6(); | ||||
|             else | ||||
|                 dst.Address = src.Address; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Maps the IPEndPoint object to an IPv6 address. Has allocation | ||||
|         /// </summary> | ||||
|         internal static IPEndPoint MapToIPv6(IPEndPoint endPoint) | ||||
|         { | ||||
|             if (endPoint.AddressFamily == AddressFamily.InterNetwork) | ||||
|                 return new IPEndPoint(endPoint.Address.MapToIPv6(), endPoint.Port); | ||||
|             return endPoint; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ using System.Resources; | |||
| [assembly: AssemblyCulture("")] | ||||
| 
 | ||||
| // Version informationr( | ||||
| [assembly: AssemblyVersion("0.0.0.1524")] | ||||
| [assembly: AssemblyFileVersion("0.0.0.1524")] | ||||
| [assembly: AssemblyVersion("0.0.0.1525")] | ||||
| [assembly: AssemblyFileVersion("0.0.0.1525")] | ||||
| [assembly: NeutralResourcesLanguageAttribute( "en-US" )] | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| { | ||||
| 	"id": "srmp", | ||||
| 	"name": "Slime Rancher Multiplayer", | ||||
| 	"version": "0.0.1524", | ||||
| 	"version": "0.0.1525", | ||||
| 	"author": "SatyPardus", | ||||
| 	"dependencies": [ | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Saty
						Saty