public void DisconnectConnection(long connectionId) { using (MonitorLock.CreateLock(m_disconnectionListLock)) { m_disconnectionList.Add(connectionId); } }
public void SendPacket(NetWrapOutgoingMessage msg, List <long> connectionIds, NetWrapOrdering delivery = NetWrapOrdering.ReliableOrdered, int sequenceChannel = 0) { if (m_valid == false) { return; } var flags = ENet.PacketFlags.None; if ((int)delivery >= 30) { flags |= ENet.PacketFlags.Reliable; } if (delivery == NetWrapOrdering.ReliableUnordered) { flags |= ENet.PacketFlags.Unsequenced; } msg.Flags = flags; foreach (var connectionId in connectionIds) { var toSendMsg = new NetWrapOutgoingMessage(msg); toSendMsg.ConnectionId = connectionId; using (MonitorLock.CreateLock(m_outgoingPacketListLocks[(m_currentOutgoingPacketListIndex + 1) % 2])) { m_outgoingPacketLists[(m_currentOutgoingPacketListIndex + 1) % 2].Add(toSendMsg); } } }
public void Shutdown(string p) { if (m_valid == false) { return; } if (peer.IsInitialized) { peer.DisconnectNow(p.GetHashCode()); } using (MonitorLock.CreateLock(hostLock)) { if (host.IsInitialized) { m_stopThread = true; m_threadStoppedEvent.WaitOne(5000); try { host.Dispose(); m_valid = false; } catch (Exception e) { Console.WriteLine("Failed to shut down ENet e:" + e); } } } }
public void Flush() { using (MonitorLock.CreateLock(hostLock)) { host.Flush(); } }
private void i_checkStartENetThread() { if (m_ENetTask == null || m_ENetTask.IsCompleted) { m_ENetTask = Task.Run(() => { Thread.CurrentThread.Name = "ENet Thread"; while (!m_stopThread || m_disconnectionList.Count != 0) { using (MonitorLock.CreateLock(m_outgoingPacketListLocks[m_currentOutgoingPacketListIndex])) { foreach (var outgoingPacket in m_outgoingPacketLists[m_currentOutgoingPacketListIndex]) { NetWrapConnection connection; if (!m_connections.TryGetValue(outgoingPacket.ConnectionId, out connection)) { continue; } if (connection.Peer.State == ENet.PeerState.Connected) { connection.Peer.Send(0, outgoingPacket.Message, outgoingPacket.MessageOffset, outgoingPacket.MessageCount, outgoingPacket.Flags); } } m_outgoingPacketLists[m_currentOutgoingPacketListIndex].Clear(); } using (MonitorLock.CreateLock(m_disconnectionListLock)) { foreach (var connectionId in m_disconnectionList) { NetWrapConnection connection; if (m_connections.TryRemove(connectionId, out connection) && connection.Peer.UserData != IntPtr.Zero) { GCHandle.FromIntPtr(connection.Peer.UserData).Free(); connection.Peer.UserData = IntPtr.Zero; } if (connection.Peer.IsInitialized && connection.Peer.State == ENet.PeerState.Connected) { connection.Peer.DisconnectLater("disconnect".GetHashCode()); } } m_disconnectionList.Clear(); } using (MonitorLock.CreateLock(m_enetEventListLocks[m_currentENetEventListIndex])) { ENet.Event enetEvent; using (MonitorLock.CreateLock(hostLock)) { if (host.Service(0, out enetEvent)) { do { m_enetEventLists[m_currentENetEventListIndex].Add(enetEvent); } while (host.CheckEvents(out enetEvent)); } } } Thread.Sleep(25); } m_threadStoppedEvent.Set(); }); } }
public bool Update() { if (m_valid == false) { return(false); } i_checkStartENetThread(); using (MonitorLock.CreateLock(m_outgoingPacketListLocks[m_currentOutgoingPacketListIndex])) { using (MonitorLock.CreateLock(m_outgoingPacketListLocks[(m_currentOutgoingPacketListIndex + 1) % 2])) { if (m_outgoingPacketLists[(m_currentOutgoingPacketListIndex + 1) % 2].Count > 0 && m_outgoingPacketLists[m_currentOutgoingPacketListIndex].Count == 0) { m_currentOutgoingPacketListIndex = (m_currentOutgoingPacketListIndex + 1) % 2; } } } using (MonitorLock.CreateLock(m_enetEventListLocks[m_currentENetEventListIndex])) { if (m_enetEventLists[m_currentENetEventListIndex].Count > 0) { m_currentENetEventListIndex = (m_currentENetEventListIndex + 1) % 2; m_enetEventLists[m_currentENetEventListIndex].Clear(); } } using (MonitorLock.CreateLock(m_enetEventListLocks[m_currentENetEventListIndex])) { foreach (var enetEvent in m_enetEventLists[(m_currentENetEventListIndex + 1) % 2]) { if (enetEvent.Type == ENet.EventType.None) { continue; } NetWrapConnection connection; if (enetEvent.Peer.UserData == IntPtr.Zero) { var peer = enetEvent.Peer; connection = new NetWrapConnection { ConnectionId = connectionIDCounter++, Peer = enetEvent.Peer }; m_connections.TryAdd(connection.ConnectionId, connection); peer.UserData = GCHandle.ToIntPtr(GCHandle.Alloc(connection)); } else { var gcHandle = GCHandle.FromIntPtr(enetEvent.Peer.UserData); connection = (NetWrapConnection)gcHandle.Target; m_connections.GetOrAdd(connection.ConnectionId, connection); } switch (enetEvent.Type) { case ENet.EventType.Connect: { // set timeouts enetEvent.Peer.SetTimeouts(5, 30000, 90000); NumConnections++; var wrappedStatus = new NetWrapConnectionStatus() { Status = NetWrapConnectionStatusEnum.Connected, EndPoint = enetEvent.Peer.GetRemoteAddress(), ConnectionId = connection.ConnectionId }; OnStatusChanged(this, wrappedStatus); } break; case ENet.EventType.Disconnect: { NumConnections--; var wrappedStatus = new NetWrapConnectionStatus() { Status = NetWrapConnectionStatusEnum.Disconnected, EndPoint = enetEvent.Peer.GetRemoteAddress(), ConnectionId = connection.ConnectionId }; OnStatusChanged(this, wrappedStatus); } break; case ENet.EventType.Receive: byte[] data = enetEvent.Packet.GetBytes(); if (data.Length >= 5 && data[0] == RPCHeader[0] && data[1] == RPCHeader[1] && data[2] == RPCHeader[2] && data[3] == RPCHeader[3]) { #if RELEASE // Needs to be #if-ed out in debug to let errors fall into the debugger try { #endif var rpcDataTemplate = new RPCData(); var msg = new NetWrapIncomingMessage(); msg.SenderConnectionId = connection.ConnectionId; rpcDataTemplate.OriginalMessage = msg; int offset = 5; for (int i = 0; i < data[4]; i++) { int blockbytes = BitConverter.ToInt32(data, offset); offset += 4; if (blockbytes < 0) { // compressed RPC call blockbytes = -blockbytes; var buffer = NetCompressByteArray.Unwrap(data, offset); var stream = new MemoryStream(buffer); RPCStream.Execute(stream, RpcDispatcher, rpcDataTemplate); } else { // uncompressed RPC call var stream = new MemoryStream(data, offset, blockbytes); RPCStream.Execute(stream, RpcDispatcher, rpcDataTemplate); } offset += blockbytes; } #if RELEASE } catch (Exception ex) { try { using (var stream = System.IO.File.AppendText("ignored-net-errors.txt")) stream.WriteLine(DateTime.Now.ToString() + " : " + ex.ToString()); } catch {} Console.WriteLine(ex.ToString()); break; } #endif } else { NetWrapIncomingMessage msg = new NetWrapIncomingMessage() { Message = data, MessageCount = data.Length, MessageOffset = 0, SenderConnectionId = connection.ConnectionId }; OnData(this, msg); } enetEvent.Packet.Dispose(); break; default: Console.WriteLine(enetEvent.Type); break; } } m_enetEventLists[(m_currentENetEventListIndex + 1) % 2].Clear(); } return(true); }