public async Task QueryAsync(CommandContext ctx, [Description("Registered name or IP.")] string name, [Description("Query port")] int queryport = 10481) { if (queryport <= 0 || queryport > 65535) { throw new InvalidCommandUsageException("Port range invalid (must be in range [1, 65535])!"); } SwatServer server = await this.Database.GetSwatServerFromDatabaseAsync(name.ToLowerInvariant()); if (server == null) { throw new CommandFailedException("Server with given name is not registered."); } SwatServerInfo info = await SwatServerInfo.QueryIPAsync(server.Ip, server.QueryPort); if (info != null) { await ctx.RespondAsync(embed : info.ToDiscordEmbed(this.ModuleColor)); } else { await this.InformFailureAsync(ctx, "No reply from server."); } }
private async Task QueryAndPrintInfoAsync(CommandContext ctx, DatabaseSwatServer server) { SwatServerInfo info = await SwatServerInfo.QueryIPAsync(server.IP, server.QueryPort); if (info is null) { await this.InformFailureAsync(ctx, "No reply from server."); return; } DiscordMessage msg = await ctx.RespondAsync(embed : info.ToDiscordEmbed(this.ModuleColor)); await msg.CreateReactionAsync(StaticDiscordEmoji.Information); await Task.Delay(250); InteractivityResult <MessageReactionAddEventArgs> rctx = await ctx.Client.GetInteractivity().WaitForEventArgsAsync <MessageReactionAddEventArgs>(e => e.Message == msg && e.Emoji == StaticDiscordEmoji.Information); if (!rctx.TimedOut) { SwatServerInfo completeInfo = await SwatServerInfo.QueryIPAsync(server.IP, server.QueryPort, complete : true); if (completeInfo is null) { await this.InformFailureAsync(ctx, "No reply from server."); return; } await msg.ModifyAsync(embed : completeInfo.ToDiscordEmbed(this.ModuleColor)); } }
public static DiscordEmbed ToDiscordEmbed(this SwatServerInfo info, DiscordColor?color = null) { var emb = new DiscordEmbedBuilder { Url = $"https://swat4stats.com/servers/{ info.Ip }:{ info.JoinPort }", Title = info.HostName, Description = $"{info.Ip}:{info.JoinPort}" }; if (!(color is null)) { emb.WithColor(color.Value); } emb.AddField("Players", info.Players + "/" + info.MaxPlayers, inline: true); emb.AddField("Game", string.IsNullOrWhiteSpace(info.Game) ? Formatter.Italic("unknown") : info.Game, inline: true); emb.AddField("Version", string.IsNullOrWhiteSpace(info.GameVersion) ? Formatter.Italic("unknown") : info.GameVersion, inline: true); emb.AddField("Game mode", string.IsNullOrWhiteSpace(info.GameMode) ? Formatter.Italic("unknown") : info.GameMode, inline: true); emb.AddField("Map", string.IsNullOrWhiteSpace(info.Map) ? Formatter.Italic("unknown") : info.Map, inline: true); emb.AddField("Round", (string.IsNullOrWhiteSpace(info.Round) ? Formatter.Italic("unknown") : info.Round) + "/" + (string.IsNullOrWhiteSpace(info.MaxRounds) ? Formatter.Italic("unknown") : info.MaxRounds), inline: true); if (info.PlayerNames.Any()) { int maxNameLen = info.PlayerNames.Max(p => p.Length); int maxScoreLen = info.PlayerScores.Max(s => s.Length); IEnumerable <string> lines = info.PlayerNames .Zip(info.PlayerScores, (p, s) => (p, s)) .OrderByDescending(tup => int.TryParse(tup.s, out int score) ? score : 0) .Select(tup => $"{tup.p.PadRight(maxNameLen)} | {tup.s.PadLeft(maxScoreLen)}"); emb.AddField("Playerlist", Formatter.BlockCode(string.Join("\n", lines))); } return(emb.Build()); }
private static void CheckCallback(object _) { if (_listeners.IsEmpty) { _ticker.Change(Timeout.Infinite, Timeout.Infinite); return; } lock (_lock) { foreach (DatabaseSwatServer server in _listeners.Keys) { SwatServerInfo info = _async.Execute(SwatServerInfo.QueryIPAsync(server.IP, server.QueryPort)); if (info is null) { foreach (DiscordChannelInfo ci in _listeners[server]) { try { if (ci.Success == true || ci.LastMessageId != ci.LastMessageId) { ci.LastMessageId = _async.Execute(ci.Channel.InformFailureAsync($"No reply from {server.IP}:{server.JoinPort}")).Id; } ci.Success = false; } catch { _listeners[server].TryRemove(ci); } } } else if (info.HasSpace) { foreach (DiscordChannelInfo ci in _listeners[server]) { try { if (ci.Success == false || ci.LastMessageId != ci.Channel.LastMessageId) { ci.LastMessageId = _async.Execute(ci.Channel.EmbedAsync($"There is space on {Formatter.Bold(info.HostName)}!", StaticDiscordEmoji.AlarmClock, DiscordColor.Black)).Id; } ci.Success = true; } catch { _listeners[server].TryRemove(ci); } } } } } }
public async Task QueryAsync(CommandContext ctx, [Description("Server IP.")] CustomIPFormat ip, [Description("Query port")] int queryport = 10481) { if (queryport <= 0 || queryport > 65535) { throw new InvalidCommandUsageException("Port range invalid (must be in range [1, 65535])!"); } var server = SwatServer.FromIP(ip.Content, queryport); SwatServerInfo info = await SwatServerInfo.QueryIPAsync(server.Ip, server.QueryPort); if (info != null) { await ctx.RespondAsync(embed : info.ToDiscordEmbed(this.ModuleColor)); } else { await this.InformFailureAsync(ctx, "No reply from server."); } }
private static void CheckCallback(object _) { if (_listeners.IsEmpty) { _ticker.Change(Timeout.Infinite, Timeout.Infinite); return; } lock (_lock) { foreach (SwatServer server in _listeners.Keys) { SwatServerInfo info = _async.Execute(SwatServerInfo.QueryIPAsync(server.Ip, server.QueryPort)); if (info == null) { foreach (DiscordChannel channel in _listeners[server]) { try { _async.Execute(channel.InformFailureAsync($"No reply from {server.Ip}:{server.JoinPort}")); } catch { _listeners[server].TryRemove(channel); } } } else if (info.HasSpace) { foreach (DiscordChannel channel in _listeners[server]) { try { _async.Execute(channel.EmbedAsync($"There is space on {Formatter.Bold(info.HostName)}!", StaticDiscordEmoji.AlarmClock, DiscordColor.Black)); } catch { _listeners[server].TryRemove(channel); } } } } } }
public async Task ServerlistAsync(CommandContext ctx) { var em = new DiscordEmbedBuilder() { Title = "Servers", Color = this.ModuleColor }; IReadOnlyList <SwatServer> servers = await this.Database.GetAllSwatServersAsync(); if (servers == null || !servers.Any()) { throw new CommandFailedException("No servers found in the database."); } SwatServerInfo[] infos = await Task.WhenAll(servers.Select(s => SwatServerInfo.QueryIPAsync(s.Ip, s.QueryPort))); foreach (SwatServerInfo info in infos.Where(i => i != null).OrderByDescending(i => int.Parse(i.Players))) { em.AddField(info.HostName, $"{Formatter.Bold(info.Players + " / " + info.MaxPlayers)} | {info.Ip}:{info.JoinPort}"); } await ctx.RespondAsync(embed : em.Build()); }
public async Task ServerlistAsync(CommandContext ctx, [Description("Server name group.")] string group = null) { var em = new DiscordEmbedBuilder { Title = "Servers", Color = this.ModuleColor, Url = "https://swat4stats.com/servers/" }; List <DatabaseSwatServer> servers; using (DatabaseContext db = this.Database.CreateContext()) { if (string.IsNullOrWhiteSpace(group)) { servers = await db.SwatServers.ToListAsync(); } else { servers = await db.SwatServers.Where(s => s.Name.Contains(group)).ToListAsync(); } } if (servers is null || !servers.Any()) { throw new CommandFailedException("No servers found in the database matching the given criteria."); } SwatServerInfo[] infos = await Task.WhenAll(servers.Select(s => SwatServerInfo.QueryIPAsync(s.IP, s.QueryPort))); foreach (SwatServerInfo info in infos.Where(i => !(i is null)).OrderByDescending(i => int.Parse(i.Players))) { em.AddField(info.HostName, $"{Formatter.Bold(info.Players + " / " + info.MaxPlayers)} | {info.Ip}:{info.JoinPort}"); } await ctx.RespondAsync(embed : em.Build()); }