/// <summary> /// Template method for common code needed in UpdateServerInfo, UpdatePlayers and UpdateRules /// </summary> private bool ExecuteUpdate(UpdateRequest request, ServerRow row, Server server, Func <Action <int>, bool> updater) { if (request.IsCancelled) { return(false); } try { row.Status = "updating " + row.Retries; request.SetDataModified(); bool ok = updater(retry => { if (request.IsCancelled) { throw new OperationCanceledException(); } if (row.Retries == 0) { Interlocked.Increment(ref request.TasksWithRetries); } row.Status = "updating " + (++row.Retries + 1); request.SetDataModified(); }); if (ok) { return(true); } Interlocked.Increment(ref request.TasksWithTimeout); } catch { } return(false); }
// shared update code #region UpdateServerAndDetails() private void UpdateServerAndDetails(UpdateRequest request, ServerRow row, bool fireRefreshSingleServerComplete) { string status = ""; try { if (request.IsCancelled) { return; } using (Server server = ServerQuery.GetServerInstance(EngineType.Source, row.EndPoint, false, request.Timeout, request.Timeout)) { row.Retries = 0; server.SendFirstPacketTwice = this.sendFirstUdpPacketTwice; server.Retries = 3; status = "timeout"; if (this.UpdateServerInfo(request, row, server)) { row.GameExtension = gameExtensions.Get((Game)(row.ServerInfo.Extra?.GameId ?? row.ServerInfo.Id)); this.UpdatePlayers(request, row, server); this.UpdateRules(request, row, server); status = "ok"; } row.RequestTimestamp = request.Timestamp; } if (request.IsCancelled) // status might have changed { return; } if (row.Retries > 0) { status += " (" + row.Retries + ")"; } } catch { // this happens when you hibernate windows and the program resumes before the network connection has be reestablished status = "network error"; } finally { row.Status = status; row.Update(); request.SetDataModified(); if (fireRefreshSingleServerComplete && !request.IsCancelled) { this.RefreshSingleServerComplete?.Invoke(this, new ServerEventArgs(row)); } if (!request.PendingTasks.IsSet) { request.PendingTasks.Signal(); } } }
private void OnMasterServerReceive(UpdateRequest request, ReadOnlyCollection <Tuple <IPEndPoint, ServerInfo> > endPoints, Exception error, bool isPartialResult) { if (request.IsCancelled) { return; } string statusText; string errorMsg = error?.Message ?? (endPoints == null ? "Timeout" : null); if (errorMsg != null) { statusText = "Error requesting server list from master server: " + errorMsg; if (request.receivedServerCount > 0) { this.AllServersReceived(request); } } else { statusText = $"Updating status of {endPoints.Count} servers..."; foreach (var ep in endPoints) { if (request.IsCancelled) { return; } if (++request.receivedServerCount > request.MaxResults) { statusText = $"Server list limited to {request.MaxResults} entries. Updating status..."; break; } else if (request.GameExtension.AcceptGameServer(ep.Item1)) { request.Servers.Add(new ServerRow(ep.Item1, request.GameExtension, ep.Item2)); } } if (!isPartialResult) { this.AllServersReceived(request); } } request.SetDataModified(); this.UpdateStatus?.Invoke(this, new TextEventArgs(statusText)); }
private void UpdateServerAndDetails(UpdateRequest request, ServerRow row, bool fireRefreshSingleServerComplete) { string status = ""; try { if (request.IsCancelled) return; using (Server server = ServerQuery.GetServerInstance(EngineType.Source, row.EndPoint, false, request.Timeout, request.Timeout)) { row.Retries = 0; server.SendFirstPacketTwice = this.sendFirstUdpPacketTwice; server.Retries = 3; status = "timeout"; var oldPing = row.ServerInfo?.Ping ?? 0; if (this.UpdateServerInfo(request, row, server)) { if (request.KeepPreviousPing && row.ServerInfo != null) row.ServerInfo.Ping = oldPing; // keep old ping so that the row isn't immediately resorted and moved this.UpdatePlayers(request, row, server); this.UpdateRules(request, row, server); status = "ok"; } row.RequestTimestamp = request.Timestamp; } if (request.IsCancelled) // status might have changed return; if (row.Retries > 0) status += " (" + row.Retries + ")"; } catch { // this happens when you hibernate windows and the program resumes before the network connection has be reestablished status = "network error"; } finally { row.Status = status; row.Update(); request.SetDataModified(); if (fireRefreshSingleServerComplete) this.RefreshSingleServerComplete?.Invoke(this, new ServerEventArgs(row)); if (!request.PendingTasks.IsSet) request.PendingTasks.Signal(); } }
private void OnMasterServerReceive(UpdateRequest request, ReadOnlyCollection<IPEndPoint> endPoints) { if (request.IsCancelled) return; string statusText; if (endPoints == null) { statusText = $"Master server request timed out after returning {request.receivedServerCount} servers (clients are limited to receive 30 packets per minute)"; if (request.receivedServerCount > 0) this.AllServersReceived(request); } else { statusText = $"Requesting batch {++request.BatchNumber} of server list..."; foreach (var ep in endPoints) { if (request.IsCancelled) return; if (ep.Address.Equals(IPAddress.Any)) { statusText = $"Master server returned {request.Servers.Count} servers"; this.AllServersReceived(request); } else if (++request.receivedServerCount >= request.MaxResults) { statusText = $"Server list limited to {request.MaxResults} entries"; this.AllServersReceived(request); break; } else if (request.GameExtension.AcceptGameServer(ep)) request.Servers.Add(new ServerRow(ep, request.GameExtension)); } } request.SetDataModified(); this.UpdateStatus?.Invoke(this, new TextEventArgs(statusText)); }
/// <summary> /// Template method for common code needed in UpdateServerInfo, UpdatePlayers and UpdateRules /// </summary> private bool ExecuteUpdate(UpdateRequest request, ServerRow row, Server server, Func<Action<int>, bool> updater) { if (request.IsCancelled) return false; try { row.Status = "updating " + row.Retries; request.SetDataModified(); bool ok = updater(retry => { if (request.IsCancelled) throw new OperationCanceledException(); if (row.Retries == 0) Interlocked.Increment(ref request.TasksWithRetries); row.Status = "updating " + (++row.Retries + 1); request.SetDataModified(); }); if (ok) return true; Interlocked.Increment(ref request.TasksWithTimeout); } catch { } return false; }