Skip to content

Commit d054ebe

Browse files
committed
Enable slash commands! Small refactor for splitting the Steam Check output into chunks.
1 parent d4bb560 commit d054ebe

8 files changed

Lines changed: 223 additions & 82 deletions

File tree

SupportBot/Checks/CheckModule.cs

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,10 @@
1111
// </copyright>
1212
// <summary></summary>
1313
// ***********************************************************************
14+
1415
using System;
1516
using Discord.Commands;
16-
using System.Net;
17-
using System.Text.Json;
1817
using System.Threading.Tasks;
19-
using SupportBot.Checks.Modal;
20-
using System.Text;
2118

2219
namespace SupportBot.Checks
2320
{
@@ -38,51 +35,15 @@ public class CheckModule : ModuleBase<SocketCommandContext>
3835
/// <param name="address">The address.</param>
3936
/// <returns>Task.</returns>
4037
[Command("check-steam")]
41-
public Task CheckSteam([Remainder][Summary("The server ip address or FQDN to check")] string address)
38+
public async Task CheckSteam([Remainder] [Summary("The server ip address or FQDN to check")] string address)
4239
{
43-
Context.Message.DeleteAsync();
44-
45-
try
46-
{
47-
var sb = new StringBuilder();
48-
49-
if (!Helpers.CheckIpValid(address))
50-
{
51-
var entries = Dns.GetHostAddresses(address);
52-
if (entries.Length > 1)
53-
{
54-
sb.Append("Multiple addresses found for this host, only the first is checked");
55-
}
56-
57-
//Set the address to the resolved IP.
58-
address = entries[0].ToString();
59-
}
60-
61-
using var webClient = new WebClient();
62-
var result = JsonSerializer.Deserialize<SteamAPIResponse>(webClient.DownloadString($"https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr={address}"));
63-
64-
if (!result.response.success) return ReplyAsync("Steam API resulted in a failure. Try again later.");
65-
66-
var totalServers = result.response.servers.Length;
67-
68-
sb.Append("Steam can see the following:\n");
69-
70-
foreach (var item in result.response.servers)
71-
{
72-
sb.Append($"**{item.gamedir}**\nApp ID: {item.appid}\nIs Secure: {item.secure}\nIs Lan:{item.lan}\nGame Port:{item.gameport}\nSpec Port:{item.specport}\n");
73-
}
40+
await Context.Message.DeleteAsync();
7441

75-
sb.Append($"Total Servers: {totalServers}");
76-
77-
return ReplyAsync(sb.ToString());
78-
79-
}
80-
catch (Exception)
42+
var response = await Helpers.CheckSteam(address);
43+
foreach (var output in response.Split(2048))
8144
{
82-
// ignored
45+
await ReplyAsync(output);
8346
}
84-
85-
return ReplyAsync("Unable to check with steam, sorry about that.");
8647
}
8748

8849
/// <summary>
@@ -94,14 +55,16 @@ public Task CheckSteam([Remainder][Summary("The server ip address or FQDN to che
9455
/// <returns>Task.</returns>
9556
[Command("check-port")]
9657
public Task CheckPort(
97-
[Summary("The server ip address or FQDN to check")] string address,
58+
[Summary("The server ip address or FQDN to check")]
59+
string address,
9860
[Summary("port to check")] int port,
99-
[Summary("Specify either: `tcp` or `udp`")] string type)
61+
[Summary("Specify either: `tcp` or `udp`")]
62+
string type)
10063
{
10164
Context.Message.DeleteAsync();
102-
65+
10366
var result = Helpers.GetPortState(address, port, 2, type.ToLower() == "udp");
104-
67+
10568
return ReplyAsync($"{port}/{type}: {Enum.GetName(result)}");
10669
}
10770
}

SupportBot/Checks/Helpers.cs

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@
44
// Created : 02-23-2021
55
//
66
// Last Modified By : Nathan Pipes
7-
// Last Modified On : 02-27-2021
7+
// Last Modified On : 09-08-2021
88
// ***********************************************************************
99
// <copyright file="Helpers.cs" company="NPipes">
1010
// Copyright (c) NPipes. All rights reserved.
1111
// </copyright>
1212
// <summary></summary>
1313
// ***********************************************************************
14+
1415
using System;
1516
using System.Net;
1617
using System.Net.Sockets;
18+
using System.Text;
19+
using System.Text.Json;
1720
using System.Threading;
1821
using System.Threading.Tasks;
22+
using SupportBot.Checks.Modal;
1923

2024
namespace SupportBot.Checks
2125
{
@@ -24,6 +28,64 @@ namespace SupportBot.Checks
2428
/// </summary>
2529
public class Helpers
2630
{
31+
/// <summary>
32+
/// Checks using the Steam Public API what is currently running on the specified server
33+
/// </summary>
34+
/// <param name="address">The hostname or IP of the server to check</param>
35+
/// <returns>List of servers running, or an error message</returns>
36+
public static async Task<string> CheckSteam(string address)
37+
{
38+
try
39+
{
40+
var sb = new StringBuilder();
41+
42+
if (!Helpers.CheckIpValid(address))
43+
{
44+
var entries = await Dns.GetHostAddressesAsync(address);
45+
if (entries.Length > 1)
46+
{
47+
sb.Append(
48+
"Multiple addresses found for this host, only the first is checked, please specify the IP you want to check next time.\n");
49+
}
50+
51+
//Set the address to the resolved IP.
52+
address = entries[0].ToString();
53+
}
54+
55+
using var webClient = new WebClient();
56+
//We are not using Async here as this will cause the method to hang the entire Task.
57+
var result = JsonSerializer.Deserialize<SteamApiResponse>(
58+
webClient.DownloadString(
59+
$"https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr={address}"));
60+
61+
if (result == null || !result.response.success)
62+
{
63+
return await Task.FromResult("Steam API resulted in a failure. Try again later.");
64+
}
65+
66+
var totalServers = result.response.servers.Length;
67+
68+
sb.Append("Steam can see the following:\n");
69+
70+
foreach (var item in result.response.servers)
71+
{
72+
sb.Append(
73+
$"**{item.gamedir}**\nApp ID: {item.appid}\nIs Secure: {item.secure}\nIs Lan:{item.lan}\nGame Port:{item.gameport}\nSpec Port:{item.specport}\n");
74+
}
75+
76+
sb.Append($"Total Servers: {totalServers}");
77+
78+
var response = sb.ToString();
79+
return await Task.FromResult(response);
80+
}
81+
catch (Exception)
82+
{
83+
// ignored
84+
}
85+
86+
return await Task.FromResult("Unable to check with steam, sorry about that.");
87+
}
88+
2789
/// <summary>
2890
/// Tries to open a network connection to a specific port retrieving the result.
2991
/// </summary>
@@ -55,7 +117,8 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
55117
var waitHandle = asyncResult.AsyncWaitHandle;
56118
try
57119
{
58-
if (asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(timeoutSeconds), false))
120+
if (asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(timeoutSeconds),
121+
false))
59122
{
60123
// The result was positive
61124
if (!asyncResult.IsCompleted)
@@ -67,6 +130,7 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
67130
result = client.Connected ? PortState.Open : PortState.Closed;
68131
}
69132
}
133+
70134
// ensure the ending-call
71135
client.EndConnect(asyncResult);
72136
}
@@ -79,15 +143,12 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
79143
catch (SocketException sockEx)
80144
{
81145
// see https://msdn.microsoft.com/en-us/library/ms740668.aspx for a list of all states
82-
switch (sockEx.NativeErrorCode)
146+
result = sockEx.NativeErrorCode switch
83147
{
84-
case 10060:
85-
result = PortState.TimedOut;
86-
break;
87-
case 10061:
88-
result = PortState.Refused;
89-
break;
90-
}
148+
10060 => PortState.TimedOut,
149+
10061 => PortState.Refused,
150+
_ => result
151+
};
91152
}
92153
catch (Exception)
93154
{
@@ -107,15 +168,14 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
107168
{
108169
client.Connect(host, port);
109170
var asyncResult = client.BeginReceive(
110-
_ =>
111-
{
112-
},
171+
_ => { },
113172
null);
114173
asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(timeoutSeconds), false);
115174
if (!asyncResult.IsCompleted)
116175
{
117176
return PortState.TimedOut;
118177
}
178+
119179
result = PortState.Open;
120180
}
121181
catch (SocketException sockEx)
@@ -138,6 +198,7 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
138198
client.Close();
139199
}
140200
}
201+
141202
return result;
142203
},
143204
token).ContinueWith(
@@ -147,6 +208,7 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
147208
{
148209
return PortState.TimedOut;
149210
}
211+
150212
return t.Result;
151213
},
152214
token).Result;
@@ -163,7 +225,7 @@ public static PortState GetPortState(string host, int port, int timeoutSeconds =
163225
{
164226
// empty catch
165227
}
166-
228+
167229
return outerResult;
168230
}
169231

@@ -208,6 +270,4 @@ public enum PortState
208270
/// </summary>
209271
Refused = 4
210272
}
211-
212-
213273
}

SupportBot/Checks/Modal/SteamAPIResponse.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace SupportBot.Checks.Modal
1616
/// <summary>
1717
/// Steam API root node.
1818
/// </summary>
19-
public class SteamAPIResponse
19+
public class SteamApiResponse
2020
{
2121
/// <summary>
2222
/// Gets or sets the response.

SupportBot/CommandHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public CommandHandler(IServiceProvider services)
5353
_services = services;
5454
}
5555

56-
private Task CommandsOnLog(LogMessage arg)
56+
private static Task CommandsOnLog(LogMessage arg)
5757
{
5858
File.AppendAllText("commands.log", arg.ToString());
5959

@@ -76,7 +76,7 @@ public async Task InstallCommandsAsync()
7676
private async Task HandleCommandAsync(SocketMessage messageParam)
7777
{
7878
// Don't process the command if it was a system message
79-
if (!(messageParam is SocketUserMessage message)) return;
79+
if (messageParam is not SocketUserMessage message) return;
8080

8181
if (!Worker.Settings.AllowedChannels.Contains(message.Channel.Id))
8282
{

SupportBot/Extensions.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
namespace SupportBot
5+
{
6+
public static class Extensions
7+
{
8+
public static IEnumerable<string> Split(this string str, int chunkSize)
9+
{
10+
if (str.Length <= chunkSize) return new[] { str };
11+
12+
return Enumerable.Range(0, str.Length / chunkSize)
13+
.Select(i => str.Substring(i * chunkSize, chunkSize));
14+
15+
}
16+
}
17+
}

SupportBot/HelpModule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public Task LvmResize()
5050
/// </summary>
5151
/// <returns>Task.</returns>
5252
[Command("wsl")]
53-
public Task WSL()
53+
public Task Wsl()
5454
{
5555
return ReplyAsync(strings.Wsl);
5656
}

SupportBot/SupportBot.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
<Product>LinuxGSM Support Bot</Product>
99
<PackageId>LinuxGSM Support Bot</PackageId>
1010
<Version>1.0.3</Version>
11+
<PackageVersion>1.0.4</PackageVersion>
1112
</PropertyGroup>
1213

1314
<ItemGroup>
14-
<PackageReference Include="Discord.Net" Version="2.3.0" />
15-
<PackageReference Include="Discord.Net.Commands" Version="2.3.0" />
16-
<PackageReference Include="LiteDB" Version="5.0.10" />
15+
<PackageReference Include="Discord.Net.Labs" Version="3.0.2" />
16+
<PackageReference Include="LiteDB" Version="5.0.11" />
1717
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
1818
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
19-
<PackageReference Include="System.Drawing.Common" Version="5.0.1" />
19+
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
2020
</ItemGroup>
2121

2222
<ItemGroup>

0 commit comments

Comments
 (0)