/// <summary> /// Starts the server with the specified config options /// </summary> /// <param name="serverConfig">Server config information</param> /// <returns>If the server has started.</returns> public bool StartServer(ServerConfig serverConfig) { // If the server is already running, we will stop and start it again if (Status == ServerStatus.Running) { StopServer(); } // Set the config Config = serverConfig; // Let the user know that we are trying to start the server CSM.Log($"Attempting to start server on port {Config.Port}..."); // Attempt to start the server _netServer.DiscoveryEnabled = true; var result = _netServer.Start(Config.Port); // If the server has not started, tell the user and return false. if (!result) { CSM.Log("The server failed to start."); StopServer(); // Make sure the server is fully stopped return(false); } try { // This async stuff is nasty, but we have to target .net 3.5 (unless cities skylines upgrades to something higher). var nat = new NatDiscoverer(); var cts = new CancellationTokenSource(); cts.CancelAfter(5000); nat.DiscoverDeviceAsync(PortMapper.Upnp, cts).ContinueWith(task => task.Result.CreatePortMapAsync(new Mapping(Protocol.Udp, Config.Port, Config.Port, "Cities Skylines Multiplayer (UDP)"))).Wait(); } catch (Exception e) { CSM.Log("Failed to automatically open port. Manual Port Forwarding is required. " + e.Message); } // Update the status Status = ServerStatus.Running; // Set up processing thread _serverProcessingThread = new Thread(ProcessEvents); _serverProcessingThread.Start(); // Initialize host player _hostPlayer = new Player(Config.Username); MultiplayerManager.Instance.PlayerList.Add(_hostPlayer.Username); // Update the console to let the user know the server is running CSM.Log("The server has started."); return(true); }
private void OnApplicationPause(bool pause) { if (Socket == null) { return; } if (pause) { Paused = true; Socket.CloseSocket(true); } else if (Paused) { if (!Socket.Start(BindAddrIPv4, BindAddrIPv6, Port, ManualMode)) { NetDebug.WriteError("[S] Cannot restore connection \"{0}\",\"{1}\" port {2}", BindAddrIPv4, BindAddrIPv6, Port); Socket.CloseSocket(false); } } }
/// <summary> /// Attempt to connect to a server /// </summary> /// <param name="clientConfig">Client config params</param> /// <returns>True if the client is connected to the server, false if not</returns> public bool Connect(ClientConfig clientConfig) { // Let the user know that we are trying to connect to a server _logger.Info($"Attempting to connect to server at {clientConfig.HostAddress}:{clientConfig.Port}..."); // if we are currently trying to connect, cancel // and try again. if (Status == ClientStatus.Connecting) { _logger.Info("Current status is 'connecting', attempting to disconnect first."); Disconnect(); } // The client is already connected so we need to // disconnect. if (Status == ClientStatus.Connected) { _logger.Info("Current status is 'connected', attempting to disconnect first."); Disconnect(); } // Set the configuration Config = clientConfig; // Start the client, if client setup fails, return out and // tell the user var result = _netClient.Start(); if (!result) { _logger.Error("The client failed to start."); ConnectionMessage = "The client failed to start."; Disconnect(); // make sure we are fully disconnected return(false); } _logger.Info("Set status to 'connecting'..."); // Try connect to server, update the status to say that // we are trying to connect. try { _netClient.Connect(Config.HostAddress, Config.Port, "CSM"); } catch (Exception ex) { ConnectionMessage = "Failed to connect."; _logger.Error(ex, $"Failed to connect to {Config.HostAddress}:{Config.Port}"); ChatLogPanel.PrintGameMessage(ChatLogPanel.MessageType.Error, $"Failed to connect: {ex.Message}"); Disconnect(); return(false); } // Start processing networking Status = ClientStatus.Connecting; ClientId = 0; // We need to wait in a loop for 30 seconds (waiting 500ms each time) // while we wait for a successful connection (Status = Connected) or a // failed connection (Status = Disconnected). var waitWatch = new Stopwatch(); waitWatch.Start(); // Try connect for 30 seconds while (waitWatch.Elapsed < TimeSpan.FromSeconds(30)) { // If we connect, exit the loop and return true if (Status == ClientStatus.Connected) { _logger.Info("Client has connected."); return(true); } // The client cannot connect for some reason, the ConnectionMessage // variable will contain why. if (Status == ClientStatus.Disconnected) { _logger.Warn("Client disconnected while in connecting loop."); Disconnect(); // make sure we are fully disconnected return(false); } // Wait 500ms Thread.Sleep(500); } // We have timed out ConnectionMessage = "Could not connect to server, timed out."; _logger.Warn("Connection timeout!"); // Did not connect Disconnect(); // make sure we are fully disconnected return(false); }
/// <summary> /// Attempt to connect to a server /// </summary> /// <param name="clientConfig">Client config params</param> /// <returns>True if the client is connected to the server, false if not</returns> public bool Connect(ClientConfig clientConfig) { // if we are currently trying to connect, cancel // and try again. if (Status == ClientStatus.Connecting) { Disconnect(); } // The client is already connected so we need to // disconnect. if (Status == ClientStatus.Connected) { Disconnect(); } // Set the config _clientConfig = clientConfig; // Let the user know that we are trying to connect to a server CSM.Log($"Attempting to connect to server at {_clientConfig.HostAddress}:{_clientConfig.Port}..."); // Start the client, if client setup fails, return out and // tell the user var result = _netClient.Start(); if (!result) { ConnectionMessage = "The client failed to start."; Disconnect(); // make sure we are fully disconnected return(false); } // Try connect to server, update the status to say that // we are trying to connect. _netClient.Connect(_clientConfig.HostAddress, _clientConfig.Port); // Start processing networking Status = ClientStatus.Connecting; // Setup processing thread _clientProcessingThread = new Thread(ProcessEvents); _clientProcessingThread.Start(); // We need to wait in a loop for 30 seconds (waiting 500ms each time) // while we wait for a successful connection (Status = Connected) or a // failed connection (Status = Disconnected). var waitWatch = new Stopwatch(); waitWatch.Start(); while (waitWatch.Elapsed < TimeSpan.FromSeconds(30)) { // If we connect, exit the loop and return true if (Status == ClientStatus.Connected) { return(true); } // The client cannot connect for some reason, the ConnectionMessage // variable will contain why. if (Status == ClientStatus.Disconnected) { Disconnect(); // make sure we are fully disconnected return(false); } // Wait 500ms Thread.Sleep(500); } // We have timed out ConnectionMessage = "Could not connect to server, timed out."; // Did not connect Disconnect(); // make sure we are fully disconnected return(false); }