public void GetNextServerCandidate_MarkIterateAllBadCandidates() { serverList.GetAllEndPoints(); var recordA = ServerRecord.CreateWebSocketServer("10.0.0.1:27030"); var recordB = ServerRecord.CreateWebSocketServer("10.0.0.2:27030"); var recordC = ServerRecord.CreateWebSocketServer("10.0.0.3:27030"); // Add all candidates and mark them bad serverList.ReplaceList(new List <ServerRecord>() { recordA, recordB, recordC }); serverList.TryMark(recordA.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad); serverList.TryMark(recordB.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad); serverList.TryMark(recordC.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad); var candidatesReturned = new HashSet <ServerRecord>(); void DequeueAndMarkCandidate() { var candidate = serverList.GetNextServerCandidate(ProtocolTypes.WebSocket); Assert.True(candidatesReturned.Add(candidate), $"Candidate {candidate.EndPoint} already seen"); Thread.Sleep(TimeSpan.FromMilliseconds(10)); serverList.TryMark(candidate.EndPoint, ProtocolTypes.WebSocket, ServerQuality.Bad); } // We must dequeue all candidates from a bad list DequeueAndMarkCandidate(); DequeueAndMarkCandidate(); DequeueAndMarkCandidate(); Assert.True(candidatesReturned.Count == 3, "All candidates returned"); }
public void GetNextServerCandidate_AllEndpointsByHostAreBad() { serverList.GetAllEndPoints(); var serverA = IPAddress.Parse("10.0.0.1"); var serverB = IPAddress.Parse("10.0.0.2"); var goodRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27015)); var neutralRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27016)); var badRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27017)); var serverBRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverB, 27017)); serverList.ReplaceList(new List <ServerRecord>() { goodRecord, neutralRecord, badRecord, serverBRecord }); serverList.TryMark(goodRecord.EndPoint, goodRecord.ProtocolTypes, ServerQuality.Good); serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Bad); // Server A's endpoints are all bad. Server B is our next candidate. var nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); Assert.Equal(serverBRecord.EndPoint, nextRecord.EndPoint); Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes); }
public void GetNextServerCandidate_IsBiasedTowardsServerOrdering() { serverList.GetAllEndPoints(); var serverA = IPAddress.Parse("10.0.0.1"); var serverB = IPAddress.Parse("10.0.0.2"); var goodRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27015)); var neutralRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27016)); var badRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverA, 27017)); var serverBRecord = ServerRecord.CreateSocketServer(new IPEndPoint(serverB, 27017)); serverList.ReplaceList(new List <ServerRecord>() { badRecord, neutralRecord, goodRecord, serverBRecord }); serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Bad); serverList.TryMark(goodRecord.EndPoint, goodRecord.ProtocolTypes, ServerQuality.Good); // Server A's endpoints were all marked bad, with goodRecord being recovered var nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); Assert.Equal(goodRecord.EndPoint, nextRecord.EndPoint); Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes); serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Good); // Server A's bad record is now at the front, having been marked good nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); Assert.Equal(badRecord.EndPoint, nextRecord.EndPoint); Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes); }
private ServerRecord GetOldestContacted() { ServerRecord oldest = null; if (servers.Count == 0) { return(oldest); } lock (servers) { DateTime now = TimeBank.CurrentTime; foreach (var server in servers) { if (now.Subtract(server.LastSendIPs).TotalMinutes >= 14) { oldest = (ServerRecord)((oldest == null) ? server : (server.LastSendIPs > oldest.LastSendIPs) ? server : oldest); } } } if (oldest != null) { oldest.TryingIPs(); } return(oldest); }
public void NullsAreEqualOperator() { ServerRecord l = null; ServerRecord r = null; Assert.True(l == r); }
public static void HandleSetServerStatus(SetServerStatusMessage message, TransitionClient client) { var server = ServerRecord.GetWorldServer(client.ServerId); ServersManager.Instance.SetServerStatus(client.ServerId, message.Status); logger.White("Server " + server.Name + " status is now " + message.Status.ToString()); }
private static async Task StoreActiveDatabaseNames(ServerRecord server, AsyncServerClient client, IAsyncDocumentSession session) { AdminStatistics adminStatistics = await client.GlobalAdmin.GetStatisticsAsync(); server.IsUnauthorized = false; server.ClusterName = adminStatistics.ClusterName; server.ServerName = adminStatistics.ServerName; server.MemoryStatistics = adminStatistics.Memory; foreach (var loadedDatabase in adminStatistics.LoadedDatabases) { var databaseRecord = await session.LoadAsync <DatabaseRecord>(server.Id + "/" + loadedDatabase.Name); if (databaseRecord == null) { databaseRecord = new DatabaseRecord { Name = loadedDatabase.Name, ServerId = server.Id, ServerUrl = server.Url }; await session.StoreAsync(databaseRecord); } databaseRecord.LoadedDatabaseStatistics = loadedDatabase; } server.LoadedDatabases = adminStatistics.LoadedDatabases.Select(database => database.Name).ToArray(); }
public static async Task FetchServerDatabasesAsync(ServerRecord server, IAsyncDocumentSession session) { var client = await ServerHelpers.CreateAsyncServerClient(session, server); try { await StoreDatabaseNames(server, client, session); // Mark server as online now, so if one of the later steps throw we'll have this value. server.NotifyServerIsOnline(); await StoreActiveDatabaseNames(server, client, session); await CheckReplicationStatusOfEachActiveDatabase(server, client, session); // Mark server as online at the LastOnlineTime. server.NotifyServerIsOnline(); } catch (HttpRequestException ex) { Log.ErrorException("Error", ex); var webException = ex.InnerException as WebException; if (webException != null) { var socketException = webException.InnerException as SocketException; if (socketException != null) { server.IsOnline = false; } } } catch (AggregateException ex) { Log.ErrorException("Error", ex); var exception = ex.ExtractSingleInnerException(); var webException = exception as WebException; if (webException != null) { var response = webException.Response as HttpWebResponse; if (response != null && response.StatusCode == HttpStatusCode.Unauthorized) { server.IsUnauthorized = true; } else { server.IsOnline = false; } } } catch (Exception ex) { Log.ErrorException("Error", ex); } finally { server.LastTriedToConnectAt = DateTimeOffset.UtcNow; } }
private void CheckFirewall() { ServerRecord server = null; DateTime now = TimeBank.CurrentTime; lock (servers) server = (ServerRecord)servers.Find((s) => now.Subtract(s.LastAskedFirewall).TotalMinutes > 5); if (server != null) { server.LastAskedFirewall = now; IPAddress ip = server.ExternalIp; if (!ip.IsLocal()) { lock (myfirewalltests) myfirewalltests.Add(server); socket.SendAsync( new CheckFirewallWanted(server.Port), new IPEndPoint(ip, server.Port)); } } else { FinishedTestingFirewall = true; } }
public void TreatsProtocolsForSameServerIndividiaully() { var record1 = ServerRecord.CreateServer(IPAddress.Loopback.ToString(), 27015, ProtocolTypes.Tcp | ProtocolTypes.Udp); var record2 = ServerRecord.CreateServer(IPAddress.Loopback.ToString(), 27016, ProtocolTypes.Tcp | ProtocolTypes.Udp); serverList.ReplaceList(new[] { record1, record2 }); var nextTcp = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); var nextUdp = serverList.GetNextServerCandidate(ProtocolTypes.Udp); Assert.Equal(record1.EndPoint, nextTcp.EndPoint); Assert.Equal(record1.EndPoint, nextUdp.EndPoint); serverList.TryMark(record1.EndPoint, ProtocolTypes.Tcp, ServerQuality.Bad); nextTcp = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); nextUdp = serverList.GetNextServerCandidate(ProtocolTypes.Udp); Assert.Equal(record2.EndPoint, nextTcp.EndPoint); Assert.Equal(record1.EndPoint, nextUdp.EndPoint); serverList.TryMark(record1.EndPoint, ProtocolTypes.Udp, ServerQuality.Bad); nextTcp = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); nextUdp = serverList.GetNextServerCandidate(ProtocolTypes.Udp); Assert.Equal(record2.EndPoint, nextTcp.EndPoint); Assert.Equal(record2.EndPoint, nextUdp.EndPoint); }
public void GetNextServerCandidate_IsBiasedTowardsServerOrdering() { serverList.GetAllEndPoints(); var goodRecord = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015)); var neutralRecord = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27016)); var badRecord = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27017)); serverList.ReplaceList(new List <ServerRecord>() { badRecord, neutralRecord, goodRecord }); serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Bad); serverList.TryMark(goodRecord.EndPoint, goodRecord.ProtocolTypes, ServerQuality.Good); var nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); Assert.Equal(neutralRecord.EndPoint, nextRecord.EndPoint); Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes); serverList.TryMark(badRecord.EndPoint, badRecord.ProtocolTypes, ServerQuality.Good); nextRecord = serverList.GetNextServerCandidate(ProtocolTypes.Tcp); Assert.Equal(badRecord.EndPoint, nextRecord.EndPoint); Assert.Equal(ProtocolTypes.Tcp, nextRecord.ProtocolTypes); }
public void TryMergeWithList_AddsToHead_AndMovesExisting() { serverList.GetAllEndPoints(); var seedList = new[] { ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27025)), ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27035)), ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27045)), ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27105)), }; serverList.ReplaceList(seedList); Assert.Equal(4, seedList.Length); var listToReplace = new[] { ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015)), ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27035)), ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27105)), }; serverList.ReplaceList(listToReplace); var addresses = serverList.GetAllEndPoints(); Assert.Equal(3, addresses.Length); Assert.Equal(listToReplace[0], addresses[0]); Assert.Equal(listToReplace[1], addresses[1]); Assert.Equal(listToReplace[2], addresses[2]); }
public bool OpenChannel(string jchannel) { ServerRecord channel = Json.Deserialize <ServerRecord>(jchannel); if (channel == null) { return(false); } if (ChatClient.ActiveChat.Channel.Equals(channel)) { return(true); } ChatClient.JoiningChannel = null; ChatClient.JoiningChannel = channel; var instance = ChatClient.OpenChannel(ChatClient.JoiningChannel, new Uri(Interop.Navigation.BaseUri)); if (instance != null) { Interop.Navigation.NavigateTo(string.Format("/chatrooms/{0}", instance.Channel.HashlinkUri)); return(true); } return(false); }
public bool DisconnectClient(AuthClient newClient) { bool succes = false; AuthClient client = AuthServer.Instance.GetClients().Find(x => x.Account != null && x.Account.Id == newClient.Account.Id); if (client != null) { client.Disconnect(); succes = true; } else { if (newClient.Account.LastSelectedServerId != 0) { TransitionClient server = TransitionServer.Instance.GetServerClient(newClient.Account.LastSelectedServerId); var serverData = ServerRecord.GetWorldServer(newClient.Account.LastSelectedServerId); if (server != null && server.IsConnected && serverData != null && serverData.Status != ServerStatusEnum.STARTING) // Online { MessagePool.SendRequest <DisconnectClientResultMessage>(server, new DisconnectClientRequestMessage { AccountId = newClient.Account.Id, }, delegate(DisconnectClientResultMessage message) { succes = message.IsSucces; }, delegate() { this.OnTransitionFailed(newClient); }); } else { succes = false; } } } return(succes); }
static async Task <IReadOnlyCollection <ServerRecord> > LoadCoreAsync(SteamConfiguration configuration, int?maxNumServers, CancellationToken cancellationToken) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } var directory = configuration.GetAsyncWebAPIInterface("ISteamDirectory"); var args = new Dictionary <string, object?> { ["cellid"] = configuration.CellID.ToString(CultureInfo.InvariantCulture) }; if (maxNumServers.HasValue) { args["maxcount"] = maxNumServers.Value.ToString(CultureInfo.InvariantCulture); } cancellationToken.ThrowIfCancellationRequested(); var response = await directory.CallAsync(HttpMethod.Get, "GetCMList", version : 1, args : args).ConfigureAwait(false); var result = ( EResult )response["result"].AsInteger(( int )EResult.Invalid); if (result != EResult.OK) { throw new InvalidOperationException(string.Format("Steam Web API returned EResult.{0}", result)); } var socketList = response["serverlist"]; var websocketList = response["serverlist_websockets"]; cancellationToken.ThrowIfCancellationRequested(); var serverRecords = new List <ServerRecord>(capacity: socketList.Children.Count + websocketList.Children.Count); foreach (var child in socketList.Children) { if (child.Value is null || !ServerRecord.TryCreateSocketServer(child.Value, out var record)) { continue; } serverRecords.Add(record); } foreach (var child in websocketList.Children) { if (child.Value is null) { continue; } serverRecords.Add(ServerRecord.CreateWebSocketServer(child.Value)); } return(serverRecords.AsReadOnly()); }
private static async Task CheckReplicationStatusOfEachActiveDatabase(ServerRecord server, AsyncServerClient client, IAsyncDocumentSession session) { await HandleDatabaseInServerAsync(server, Constants.SystemDatabase, client, session); foreach (var databaseName in server.LoadedDatabases) { await HandleDatabaseInServerAsync(server, databaseName, client.ForDatabase(databaseName), session); } }
internal CMListCallback(CMsgClientCMList cmMsg) { var cmList = cmMsg.cm_addresses .Zip(cmMsg.cm_ports, (addr, port) => ServerRecord.CreateSocketServer(new IPEndPoint(NetHelpers.GetIPAddress(addr), ( int )port))); var websocketList = cmMsg.cm_websocket_addresses.Select((addr) => ServerRecord.CreateWebSocketServer(addr)); Servers = new ReadOnlyCollection <ServerRecord>(cmList.Concat(websocketList).ToList()); }
private void EnsureServerRecordExists(string url) { if (!server_records.ContainsKey(url)) { ServerRecord server_record = new ServerRecord(); server_record.url = url; server_records[server_record.url] = server_record; } }
/// <summary> /// Connects this client to a Steam3 server. /// This begins the process of connecting and encrypting the data channel between the client and the server. /// Results are returned asynchronously in a <see cref="SteamClient.ConnectedCallback"/>. /// If the server that SteamKit attempts to connect to is down, a <see cref="SteamClient.DisconnectedCallback"/> /// will be posted instead. /// SteamKit will not attempt to reconnect to Steam, you must handle this callback and call Connect again /// preferrably after a short delay. /// </summary> /// <param name="cmServer"> /// The <see cref="IPEndPoint"/> of the CM server to connect to. /// If <c>null</c>, SteamKit will randomly select a CM server from its internal list. /// </param> public void Connect(ServerRecord cmServer = null) { lock ( connectionLock ) { this.Disconnect(); Debug.Assert(connection == null); Debug.Assert(connectionCancellation == null); connectionCancellation = new CancellationTokenSource(); var token = connectionCancellation.Token; ExpectDisconnection = false; Task <ServerRecord> recordTask = null; if (cmServer == null) { recordTask = Servers.GetNextServerCandidateAsync(Configuration.ProtocolTypes); } else { recordTask = Task.FromResult(cmServer); } connectionSetupTask = recordTask.ContinueWith(t => { if (token.IsCancellationRequested) { DebugLog.WriteLine(nameof(CMClient), "Connection cancelled before a server could be chosen."); OnClientDisconnected(userInitiated: true); return; } else if (t.IsFaulted || t.IsCanceled) { DebugLog.WriteLine(nameof(CMClient), "Server record task threw exception: {0}", t.Exception); OnClientDisconnected(userInitiated: false); return; } var record = t.Result; connection = CreateConnection(record.ProtocolTypes & Configuration.ProtocolTypes); connection.NetMsgReceived += NetMsgReceived; connection.Connected += Connected; connection.Disconnected += Disconnected; connection.Connect(record.EndPoint, ( int )ConnectionTimeout.TotalMilliseconds); }, TaskContinuationOptions.ExecuteSynchronously).ContinueWith(t => { if (t.IsFaulted) { DebugLog.WriteLine(nameof(CMClient), "Unhandled exception when attempting to connect to Steam: {0}", t.Exception); OnClientDisconnected(userInitiated: false); } }, TaskContinuationOptions.ExecuteSynchronously); } }
public void SetServerStatus(ushort serverId, ServerStatusEnum state) { ServerRecord.SetServerStatus(serverId, state); foreach (var client in AuthServer.Instance.GetClients()) { client.SendServerList(); } }
public void NullIsNotEqual() { var s = ServerRecord.CreateWebSocketServer("host:1"); Assert.True(s != null); Assert.True(null != s); Assert.False(s.Equals(null)); Assert.False(s == null); Assert.False(null == s); }
public ServerRecord GetServerRecord() { if (IsWebSocket) { return(ServerRecord.CreateWebSocketServer(Address)); } ServerRecord.TryCreateSocketServer(Address, out var record); return(record); }
private static void WriteValidity(ServerRecord server) { if (server.IsValid) { return; } Console.ForegroundColor = ConsoleColor.Red; Console.Out.Write(" <INVALID>"); Console.ResetColor(); }
private void ListServer(ServerRecord server, int position) { Console.Out.Write(_serverPool.Default == server.Name ? "* " : " "); Console.Out.Write(position); Console.Out.Write(") "); WriteName(server.Name, server.Colour); Console.Out.Write($" ({server.Host}:{server.Port})"); WriteValidity(server); Console.Out.WriteLine(); }
public void UnregisterWorld(ushort serverId) { ServerRecord world = ServerRecord.GetWorldServer(serverId); if (world != null) { this.SetServerStatus(serverId, ServerStatusEnum.OFFLINE); logger.White("Server Unregistred (" + world.Name + ")"); } }
public void DifferentEndPointsAndProtocolsAreNotEqual() { var l = ServerRecord.CreateServer("host", 1, ProtocolTypes.Tcp); var r = ServerRecord.CreateServer("host", 2, ProtocolTypes.WebSocket); Assert.True(l != r); Assert.True(r != l); Assert.False(l == r); Assert.False(r == l); Assert.False(l.Equals(r)); Assert.False(r.Equals(l)); }
public void CanTryCreateSocketServer() { Assert.True(ServerRecord.TryCreateSocketServer("127.0.0.1:1234", out var record)); Assert.NotNull(record); Assert.Equal(new IPEndPoint(IPAddress.Loopback, 1234), record.EndPoint); Assert.Equal(ProtocolTypes.Tcp | ProtocolTypes.Udp, record.ProtocolTypes); Assert.True(ServerRecord.TryCreateSocketServer("192.168.0.1:5678", out record)); Assert.NotNull(record); Assert.Equal(new IPEndPoint(IPAddress.Parse("192.168.0.1"), 5678), record.EndPoint); Assert.Equal(ProtocolTypes.Tcp | ProtocolTypes.Udp, record.ProtocolTypes); }
public void TryMark_ReturnsFalse_IfServerNotInList() { var record = ServerRecord.CreateSocketServer(new IPEndPoint(IPAddress.Loopback, 27015)); serverList.ReplaceList(new List <ServerRecord>() { record }); var marked = serverList.TryMark(new IPEndPoint(IPAddress.Loopback, 27016), record.ProtocolTypes, ServerQuality.Good); Assert.False(marked); }
public static void ReleasServerRecord(ServerRecord serverRecord) { if (_servers.ContainsKey(serverRecord)) { var uses = _servers[serverRecord]; uses -= 1; if (uses < 0) { uses = 0; } _servers[serverRecord] = uses; } }
/// <summary> /// Load a list of servers from the Steam Directory. /// </summary> /// <param name="configuration">Configuration Object</param> /// <param name="cancellationToken">Cancellation Token</param> /// <returns>A <see cref="System.Threading.Tasks.Task"/> with the Result set to an enumerable list of <see cref="ServerRecord"/>s.</returns> public static Task <IReadOnlyCollection <ServerRecord> > LoadAsync(SteamConfiguration configuration, CancellationToken cancellationToken) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } var directory = configuration.GetAsyncWebAPIInterface("ISteamDirectory"); var args = new Dictionary <string, string> { ["cellid"] = configuration.CellID.ToString(CultureInfo.InvariantCulture) }; cancellationToken.ThrowIfCancellationRequested(); var task = directory.CallAsync(HttpMethod.Get, "GetCMList", version: 1, args: args); return(task.ContinueWith(t => { var response = task.Result; var result = ( EResult )response["result"].AsInteger(( int )EResult.Invalid); if (result != EResult.OK) { throw new InvalidOperationException(string.Format("Steam Web API returned EResult.{0}", result)); } var socketList = response["serverlist"]; var websocketList = response["serverlist_websockets"]; cancellationToken.ThrowIfCancellationRequested(); var serverRecords = new List <ServerRecord>(capacity: socketList.Children.Count + websocketList.Children.Count); foreach (var child in socketList.Children) { if (!NetHelpers.TryParseIPEndPoint(child.Value, out var endpoint)) { continue; } serverRecords.Add(ServerRecord.CreateSocketServer(endpoint)); } foreach (var child in websocketList.Children) { serverRecords.Add(ServerRecord.CreateWebSocketServer(child.Value)); } return (IReadOnlyCollection <ServerRecord>)serverRecords; }, cancellationToken, TaskContinuationOptions.NotOnCanceled | TaskContinuationOptions.NotOnFaulted, TaskScheduler.Current)); }