private Task PopulateLocalServerAsync(ConcurrentBag <Server> servers, RegistryKey hive, string instance, CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            return(Task.Run(() =>
            {
                try
                {
                    var localServer = new LocalServer();

                    localServer.Populate(hive, instance);

                    var server = localServer.ToServer();

                    servers.Add(server);

                    OnLocalServerDiscovered?.Invoke(this, localServer);
                    OnServerDiscovered?.Invoke(this, server);
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }
            }, cancellationToken));
        }
 private void SetEventHandlers(Options opts)
 {
     opts.AsyncErrorEventHandler       += (sender, args) => OnAsyncError?.Invoke(this, ErrorEventArguments.FromNatsEntity(args));
     opts.ServerDiscoveredEventHandler += (sender, args) => OnServerDiscovered?.Invoke(this, ConnectionEventArguments.FromNatsEntity(args));
     opts.ClosedEventHandler           += (sender, args) => OnClosed?.Invoke(this, ConnectionEventArguments.FromNatsEntity(args));
     opts.DisconnectedEventHandler     += (sender, args) => OnDisconnected?.Invoke(this, ConnectionEventArguments.FromNatsEntity(args));
 }
        /// <summary>
        /// Starts the broadcast listener for discovery
        /// </summary>
        private void StartBroadcastListener()
        {
            _listenerUDPThread = new Thread(async() =>
            {
                try
                {
                    ListenerUDP = new UdpClient();
                    ListenerUDP.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    ListenerUDP.ExclusiveAddressUse = false;
                    ListenerUDP.Client.Bind(new IPEndPoint(IPAddress.Any, BroadcastPort));
                    IPEndPoint broadcastAddress = new IPEndPoint(IPAddress.Broadcast, BroadcastPort);
                    string myIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork).ToString();
                    while (Active)
                    {
                        try
                        {
                            UdpReceiveResult received = await ListenerUDP.ReceiveAsync();
                            string ip = received.RemoteEndPoint.ToString();
                            if (ip.Contains(":"))
                            {
                                ip = ip.Substring(0, ip.IndexOf(':'));
                            }

                            if (ip != myIP)
                            {
                                string msg = Encoding.UTF8.GetString(received.Buffer);
                                if (msg.StartsWith("BLENDFARM||||"))
                                {
                                    string[] broadcastParts = msg.Split("||||");
                                    string name             = broadcastParts[1];
                                    int port = int.Parse(broadcastParts[2]);
                                    OnServerDiscovered?.Invoke(name, ip, port);
                                }
                            }
                            Thread.Sleep(100);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"Failed to receive broadcast due to:" + ex.Message);
                            Thread.Sleep(1000);
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnBroadcastException?.Invoke(this, ex);
                }
            });
            _listenerUDPThread.Start();
        }
        private Task ProcessResponse(ConcurrentBag <Server> servers, byte[] buffer, IPEndPoint responder, CancellationToken cancellationToken)
        {
            _logger?.LogDebug(LoggingExtensions.CurrentFunction());

            return(Task.Run(() =>
            {
                try
                {
                    var response = SQL.Network.NetworkServerResponse.Parse(buffer, responder);
                    if (response == null)
                    {
                        return;
                    }

                    var networkServers = SQL.Network.NetworkServers.Parse(response);
                    if (networkServers.Count == 0)
                    {
                        return;
                    }

                    foreach (var networkServer in networkServers)
                    {
                        var server = networkServer.ToServer();

                        servers.Add(server);

                        OnNetworkServerDiscovered?.Invoke(this, networkServer);
                        OnServerDiscovered?.Invoke(this, server);
                    }
                }
                catch (TaskCanceledException)
                {
                    _logger?.LogDebug($"[{LoggingExtensions.CurrentFunction()}] Cancelled");
                }
            }, cancellationToken));
        }
Exemple #5
0
        /// <summary>
        /// Invoked when the network peer has received a message
        /// </summary>
        /// <param name="state">The object that invoked this (NetPeer)</param>
        private void MessageReceived(object state)
        {
            // Get the incoming message
            NetIncomingMessage inMsg = ((NetPeer)state).ReadMessage();

            // We don't want the server to crash on one bad packet
            try
            {
                // Determine the message type to correctly handle it
                switch (inMsg.MessageType)
                {
                // Handle when a client's status has changed
                case NetIncomingMessageType.StatusChanged:
                    // Gets the status and reason
                    NetConnectionStatus status = (NetConnectionStatus)inMsg.ReadByte();
                    string reason = inMsg.ReadString();

                    // Depending on the status, we handle players joining or leaving
                    switch (status)
                    {
                    case NetConnectionStatus.Disconnected:

                        // If the reason the is shutdown message, we're good
                        if (reason.Equals(NetSettings.DEFAULT_SERVER_SHUTDOWN_MESSAGE))
                        {
                            OnDisconnected?.Invoke(this, EventArgs.Empty);
                        }
                        // Otherwise if the reason is that \/ , then we timed out
                        else if (reason.Equals("Failed to establish connection - no response from remote host", StringComparison.InvariantCultureIgnoreCase))
                        {
                            OnConnectionTimedOut?.Invoke(this, EventArgs.Empty);

                            OnDisconnected?.Invoke(this, EventArgs.Empty);
                        }
                        else if (reason.StartsWith("You have been kicked:"))
                        {
                            OnKicked?.Invoke(this, reason);

                            OnDisconnected?.Invoke(this, EventArgs.Empty);
                        }
                        // Otherwise the connection failed for some other reason
                        else
                        {
                            OnDisconnected?.Invoke(this, EventArgs.Empty);
                        }

                        if (isApproving)
                        {
                            OnConnectionFailed?.Invoke(this, reason);
                        }

                        isApproving = false;

                        // Clear local state and forget connected server tag
                        myLocalState.Clear();
                        myConnectedServer = null;
                        isReady           = false;
                        isHost            = false;
                        myKnownPlayers.Clear();
                        myLocalState.Clear();
                        myHand.Clear();

                        break;

                    case NetConnectionStatus.RespondedAwaitingApproval:
                        isApproving = true;
                        break;

                    // We connected
                    case NetConnectionStatus.Connected:
                        isApproving = false;
                        // invoked the onConnected event
                        OnConnected?.Invoke(this, EventArgs.Empty);
                        break;
                    }

                    break;

                // Handle when the server has received a discovery request
                case NetIncomingMessageType.DiscoveryResponse:
                    // Read the server tag from the packet
                    ServerTag serverTag = ServerTag.ReadFromPacket(inMsg);

                    // Notify that we discovered a server
                    OnServerDiscovered?.Invoke(this, serverTag);

                    break;

                // Handles when the server has received data
                case NetIncomingMessageType.Data:
                    HandleMessage(inMsg);
                    break;
                }
            }
            // An exception has occured parsing the packet
            catch (Exception e)
            {
                //Log the exception
                Logger.Write(e);
            }
        }