/// <summary>Launch the game controller.</summary> /// <param name="console">null when running controller in a single player game</param> public static void Launch(ServerConsole console = null) { _serverConsole = console; Players = new ConcurrentDictionary<int, NetworkPlayer>(); AdminPassword = Settings.Random.Next(10000000, 99999999).ToString(); //default an 8 digit admin password if (File.Exists(Settings.WorldFilePath)) { WriteToServerConsoleLog(string.Format("Loading world: {0}", Settings.WorldFilePath)); WorldData.LoadFromDisk(); WorldData.IsLoaded = true; } else { throw new Exception("World file not found: " + Settings.WorldFilePath); } if (!Config.IsSinglePlayer) { WriteToServerConsoleLog("Binding listener to TCP port " + TCP_LISTENER_PORT); _tcpListener = new TcpListener(System.Net.IPAddress.Any, TCP_LISTENER_PORT); _tcpListenerThread = new Thread(ListenForNewConnectionThread) { IsBackground = true, Name = "ListenForNewConnectionThread" }; _tcpListenerThread.Start(); WriteToServerConsoleLog("Listener started."); } Settings.SaveToDiskEveryMinuteThread = new Thread(SaveToDiskEveryMinuteThread) { IsBackground = true, Priority = ThreadPriority.Lowest, Name = "SaveToDiskEveryMinuteThread" }; //lowest priority makes it significantly less choppy when saving in single-player Settings.SaveToDiskEveryMinuteThread.Start(); if (Config.IsServer) { _updateTimer = new System.Timers.Timer(1000 / Constants.UPDATES_PER_SECOND) { AutoReset = true }; _updateTimer.Elapsed += UpdateHandler; _updateTimer.Start(); UpdateStopwatch.Start(); //start a thread to run periodic server tasks on a regular interval new Thread(() => { while (true) { Thread.Sleep(30000); //30 seconds //send sync action to each player foreach (var player in Players.Values) new ServerSync(SkyHost.SunAngleRadians, player).Send(); } // ReSharper disable FunctionNeverReturns }) {IsBackground = true, Priority = ThreadPriority.Normal, Name = "Server30SecondTasks"}.Start(); // ReSharper restore FunctionNeverReturns } }