private async Task DoLocalUpdate() { try { foreach (var registration in this._serverRegistrations) { ServerStatusUpdate statusUpdate = new ServerStatusUpdate(); try { Logger.Info($"{nameof(DoLocalUpdate)} Start: {registration.LocalEndpoint}"); statusUpdate = await GenerateServerStatusUpdateAsync(registration); PostServerStatusUpdate(registration, registration.UpdateCallback, statusUpdate); } catch (Exception ex) { // We don't want to stop other registration queries or break the ActionBlock Logger.Error($"{nameof(DoLocalUpdate)} - Exception in local update. {ex.Message}\r\n{ex.StackTrace}"); Debugger.Break(); } finally { Logger.Info($"{nameof(DoLocalUpdate)} End: {registration.LocalEndpoint}: {statusUpdate.Status}"); } } } finally { Task.Delay(Config.Default.ServerStatusWatcher_LocalStatusQueryDelay).ContinueWith(_ => _eventQueue.Post(DoLocalUpdate)).DoNotWait(); } }
private async Task <ServerStatusUpdate> GenerateServerStatusUpdateAsync(ServerStatusUpdateRegistration registration) { var registrationKey = registration.SteamEndpoint.ToString(); // // First check the process status // var processStatus = GetServerProcessStatus(registration, out Process process); switch (processStatus) { case ServerProcessStatus.NotInstalled: return(new ServerStatusUpdate { Status = WatcherServerStatus.NotInstalled }); case ServerProcessStatus.Stopped: return(new ServerStatusUpdate { Status = WatcherServerStatus.Stopped }); case ServerProcessStatus.Unknown: return(new ServerStatusUpdate { Status = WatcherServerStatus.Unknown }); case ServerProcessStatus.Running: break; default: Debugger.Break(); break; } var currentStatus = WatcherServerStatus.Initializing; // // If the process was running do we then perform network checks. // Logger.Info($"{nameof(GenerateServerStatusUpdateAsync)} Checking server local network status at {registration.LocalEndpoint}"); // get the server information direct from the server using local connection. GetLocalNetworkStatus(registration.GameFile, registration.LocalEndpoint, out QueryMaster.ServerInfo localInfo, out int onlinePlayerCount); if (localInfo != null) { currentStatus = WatcherServerStatus.RunningLocalCheck; // // Now that it's running, we can check the publication status. // Logger.Info($"{nameof(GenerateServerStatusUpdateAsync)} Checking server public status direct at {registration.SteamEndpoint}"); // get the server information direct from the server using public connection. var serverStatus = CheckServerStatusDirect(registration.SteamEndpoint); // check if the server returned the information. if (!serverStatus) { // server did not return any information var nextExternalStatusQuery = _nextExternalStatusQuery.ContainsKey(registrationKey) ? _nextExternalStatusQuery[registrationKey] : DateTime.MinValue; if (DateTime.Now >= nextExternalStatusQuery) { currentStatus = WatcherServerStatus.RunningExternalCheck; if (!string.IsNullOrWhiteSpace(Config.Default.ServerStatusUrlFormat)) { Logger.Info($"{nameof(GenerateServerStatusUpdateAsync)} Checking server public status via api at {registration.SteamEndpoint}"); // get the server information direct from the server using external connection. var uri = new Uri(string.Format(Config.Default.ServerStatusUrlFormat, Config.Default.ServerManagerCode, App.Instance.Version, registration.SteamEndpoint.Address, registration.SteamEndpoint.Port)); serverStatus = await NetworkUtils.CheckServerStatusViaAPI(uri, registration.SteamEndpoint); } _nextExternalStatusQuery[registrationKey] = DateTime.Now.AddMilliseconds(Config.Default.ServerStatusWatcher_RemoteStatusQueryDelay); } } // check if the server returned the information. if (serverStatus) { currentStatus = WatcherServerStatus.Published; } } var statusUpdate = new ServerStatusUpdate { Process = process, Status = currentStatus, ServerInfo = localInfo, OnlinePlayerCount = onlinePlayerCount, }; return(await Task.FromResult(statusUpdate)); }
private void PostServerStatusUpdate(ServerStatusUpdateRegistration registration, Action <IAsyncDisposable, ServerStatusUpdate> callback, ServerStatusUpdate statusUpdate) { _eventQueue.Post(() => { if (this._serverRegistrations.Contains(registration)) { try { callback(registration, statusUpdate); } catch (Exception ex) { DebugUtils.WriteFormatThreadSafeAsync("Exception during local status update callback: {0}\n{1}", ex.Message, ex.StackTrace).DoNotWait(); } } return(TaskUtils.FinishedTask); }); }