Skip to content

Commit c646bbc

Browse files
committed
Gamedig support, initial support for a web API
1 parent 9fba644 commit c646bbc

6 files changed

Lines changed: 234 additions & 20 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Microsoft.AspNetCore.Mvc;
4+
using SupportBot.Modules;
5+
6+
namespace SupportBot.Controllers
7+
{
8+
[Route("api/[controller]")]
9+
[ApiController]
10+
public class CheckController : ControllerBase
11+
{
12+
[HttpGet("gamedig")]
13+
public async Task<IActionResult> GamedigAsync(string type, string address)
14+
{
15+
var result = await Helpers.GameDig(type, address);
16+
17+
if (result != null)
18+
{
19+
return Ok(result);
20+
}
21+
22+
return BadRequest();
23+
}
24+
25+
[HttpGet("steam")]
26+
public async Task<IActionResult> SteamAsync(string address)
27+
{
28+
var result = await Helpers.CheckSteam(address);
29+
30+
if (result != null)
31+
{
32+
return Ok(result);
33+
}
34+
35+
return BadRequest();
36+
}
37+
38+
39+
[HttpGet("port")]
40+
public IActionResult Port(string address, int port, bool useUdp)
41+
{
42+
return Ok(Enum.GetName(Helpers.GetPortState(address, port, 2, useUdp)));
43+
}
44+
}
45+
}

SupportBot/Modules/CheckModule.cs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public async Task CheckSteam(
4848
var steamCollection = _databaseService.SteamChecks();
4949

5050
var embed = new EmbedBuilder();
51-
embed.WithImageUrl($"https://cdn.cloudflare.steamstatic.com/steam/apps/{response.servers[0].appid}/header.jpg")
51+
embed.WithImageUrl(
52+
$"https://cdn.cloudflare.steamstatic.com/steam/apps/{response.servers[0].appid}/header.jpg")
5253
.AddField("Game", response.servers[0].gamedir, true)
5354
.AddField("Address", response.servers[0].addr, true)
5455
.AddField("App ID",
@@ -71,6 +72,7 @@ public async Task CheckSteam(
7172
menuBuilder.AddOption($"[{server.gamedir}]: {server.addr}", index.ToString(),
7273
isDefault: 0 == index);
7374
}
75+
7476
var builder = new ComponentBuilder()
7577
.WithSelectMenu(menuBuilder);
7678

@@ -91,17 +93,102 @@ public async Task CheckSteam(
9193
}
9294
}
9395

96+
[SlashCommand("gamedig", "Runs a gamedig query on the specified server")]
97+
public async Task GameDig(
98+
[Choice("Valheim", "valheim")]
99+
[Choice("Counter-Strike: Global Offensive", "csgo")]
100+
[Choice("Counter-Strike 2", "cs2")]
101+
[Choice("Project Zomboid", "przomboid")]
102+
[Choice("Ark: Survival Evolved", "arkse")]
103+
[Choice("Minecraft", "minecraft")]
104+
[Choice("Teamspeak 3", "teamspeak3")]
105+
[Choice("Rust", "rust")]
106+
[Choice("7 Days to Die", "7d2d")]
107+
[Choice("Minecraft: Bedrock Edition", "minecraftpe")]
108+
[Choice("Garry's Mod", "garrysmod")]
109+
[Choice("Team Fortress 2", "tf2")]
110+
[Choice("Left 4 Dead 2 (2009)", "left4dead2")]
111+
[Choice("Counter-Strike 1.6", "cs16")]
112+
[Choice("Counter-Strike: Source", "css")]
113+
[Choice("DayZ", "dayz")]
114+
[Choice("Terraria", "terraria")]
115+
[Choice("ARMA 3", "arma3")]
116+
[Choice("Assetto Corsa", "assettocorsa")]
117+
[Choice("Unreal Tournament", "ut")]
118+
[Choice("Core Keeper", "corekeeper")]
119+
[Choice("Insurgency: Sandstorm", "insurgencysandstorm")]
120+
[Choice("Squad", "squad")]
121+
[Choice("Insurgency", "insurgency")]
122+
[Choice("Killing Floor 2", "killingfloor2")]
123+
string type,
124+
[Summary(description: "The server ip address or FQDN to check")]
125+
string address)
126+
{
127+
await DeferAsync(true);
128+
129+
try
130+
{
131+
var result = await Helpers.GameDig(type, address);
132+
133+
var embed = new EmbedBuilder();
134+
135+
embed.WithTitle(result.name)
136+
.AddField("Map", result.map, true)
137+
.AddField("Players", $"{result.players.Length}/{result.maxplayers}", true)
138+
.AddField("Ping", result.ping, true)
139+
.WithFooter($"Connect {result.connect}")
140+
.WithColor(Color.Blue);
141+
142+
await FollowupAsync(embed: embed.Build(), ephemeral: true);
143+
}
144+
catch (Exception exc)
145+
{
146+
await FollowupAsync($"Error, please try again later: {exc}");
147+
}
148+
}
149+
150+
[SlashCommand("gamedig2", "Runs a gamedig query on the specified server")]
151+
public async Task GameDigType(
152+
[Summary(description: "https://github.com/gamedig/node-gamedig/blob/HEAD/GAMES_LIST.md")]
153+
string type,
154+
[Summary(description: "The server ip address or FQDN to check")]
155+
string address)
156+
{
157+
await DeferAsync(true);
158+
159+
try
160+
{
161+
var result = await Helpers.GameDig(type, address);
162+
163+
var embed = new EmbedBuilder();
164+
165+
embed.WithTitle(result.name)
166+
.AddField("Map", result.map, true)
167+
.AddField("Players", $"{result.players.Length}/{result.maxplayers}", true)
168+
.AddField("Ping", result.ping, true)
169+
.WithFooter($"Connect {result.connect}")
170+
.WithColor(Color.Blue);
171+
172+
await FollowupAsync(embed: embed.Build(), ephemeral: true);
173+
}
174+
catch (Exception exc)
175+
{
176+
await FollowupAsync($"Error, please try again later: {exc}");
177+
}
178+
}
179+
94180
[ComponentInteraction("ss-s")]
95181
public async Task ProcessSteamCheckServerSelection(string[] selectedServer)
96182
{
97183
await DeferAsync(true);
98184

99185
var serverIndex = Convert.ToInt32(selectedServer[0]);
100186
var steamCollection = _databaseService.SteamChecks();
101-
187+
102188
try
103189
{
104-
var steamChecks = steamCollection.FindOne(x => x.Id == ((SocketMessageComponent)Context.Interaction).Message.Id);
190+
var steamChecks =
191+
steamCollection.FindOne(x => x.Id == ((SocketMessageComponent)Context.Interaction).Message.Id);
105192

106193
var menuBuilder = new SelectMenuBuilder()
107194
.WithPlaceholder("Select a server")
@@ -120,7 +207,8 @@ public async Task ProcessSteamCheckServerSelection(string[] selectedServer)
120207

121208
var embed = new EmbedBuilder();
122209

123-
embed.WithImageUrl($"https://cdn.cloudflare.steamstatic.com/steam/apps/{steamChecks.SteamResponse.servers[serverIndex].appid}/header.jpg")
210+
embed.WithImageUrl(
211+
$"https://cdn.cloudflare.steamstatic.com/steam/apps/{steamChecks.SteamResponse.servers[serverIndex].appid}/header.jpg")
124212
.AddField("Game", steamChecks.SteamResponse.servers[serverIndex].gamedir, true)
125213
.AddField("Address", steamChecks.SteamResponse.servers[serverIndex].addr, true)
126214
.AddField("App ID",

SupportBot/Modules/Helpers.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Net;
34
using System.Net.Http;
45
using System.Net.Sockets;
@@ -51,6 +52,45 @@ await webClient.GetStringAsync(
5152

5253
return null;
5354
}
55+
56+
/// <summary>
57+
/// Makes a GameDig Query to the specified server.
58+
/// </summary>
59+
/// <param name="type">The game type for gamedig</param>
60+
/// <param name="address">The hostname or IP of the server to check</param>
61+
/// <returns>GameDigResult or null</returns>
62+
public static async Task<GameDigResult> GameDig(string type, string address)
63+
{
64+
try
65+
{
66+
var psi = new ProcessStartInfo
67+
{
68+
FileName = "npx",
69+
Arguments = $"gamedig --type {type} {address}",
70+
RedirectStandardOutput = true,
71+
UseShellExecute = false
72+
};
73+
74+
Process process = new Process { StartInfo = psi };
75+
process.Start();
76+
77+
string output = await process.StandardOutput.ReadToEndAsync();
78+
await process.WaitForExitAsync();
79+
80+
return JsonSerializer.Deserialize<GameDigResult>(output);
81+
82+
}
83+
catch (Exception exc)
84+
{
85+
Console.WriteLine(exc.ToString());
86+
// ignored
87+
}
88+
89+
return null;
90+
}
91+
92+
93+
5494

5595
/// <summary>
5696
/// Tries to open a network connection to a specific port retrieving the result.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace SupportBot.Modules.Modal;
2+
3+
public class GameDigResult
4+
{
5+
public string name { get; set; }
6+
public string map { get; set; }
7+
public bool password { get; set; }
8+
public Raw raw { get; set; }
9+
public int maxplayers { get; set; }
10+
public Players[] players { get; set; }
11+
public object[] bots { get; set; }
12+
public string connect { get; set; }
13+
public int ping { get; set; }
14+
}
15+
16+
public class Raw
17+
{
18+
public int protocol { get; set; }
19+
public string folder { get; set; }
20+
public string game { get; set; }
21+
public int appId { get; set; }
22+
public int numplayers { get; set; }
23+
public int numbots { get; set; }
24+
public string listentype { get; set; }
25+
public string environment { get; set; }
26+
public int secure { get; set; }
27+
public string version { get; set; }
28+
public string steamid { get; set; }
29+
public string[] tags { get; set; }
30+
}
31+
32+
public class Players
33+
{
34+
public string name { get; set; }
35+
public Raw1 raw { get; set; }
36+
}
37+
38+
public class Raw1
39+
{
40+
public int score { get; set; }
41+
public double time { get; set; }
42+
}

SupportBot/Program.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
// ***********************************************************************
2-
// Assembly : SupportBot
3-
// Author : Grimston
4-
// Created : 01-24-2020
5-
//
6-
// Last Modified By : Grimston
7-
// Last Modified On : 02-20-2021
8-
// ***********************************************************************
9-
// <copyright file="Program.cs" company="NPipes">
10-
// Copyright (c) NPipes. All rights reserved.
11-
// </copyright>
12-
// <summary></summary>
13-
// ***********************************************************************
14-
151
using System.Net.Http;
162
using System.Reflection;
173
using Discord.Commands;
@@ -45,7 +31,15 @@
4531
builder.Services.AddSingleton<DatabaseService>();
4632
builder.Services.AddSingleton(x => new InteractionService(x.GetRequiredService<DiscordSocketClient>()));
4733
builder.Services.AddHostedService<Worker>();
48-
34+
35+
builder.Services.AddControllers();
36+
4937
var app = builder.Build();
50-
38+
39+
app.UseHttpsRedirection();
40+
41+
app.UseAuthorization();
42+
43+
app.MapControllers();
44+
5145
app.Run();

SupportBot/SupportBot.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@
3333
<Generator>ResXFileCodeGenerator</Generator>
3434
</EmbeddedResource>
3535
</ItemGroup>
36+
37+
<ItemGroup>
38+
<Folder Include="Pages\" />
39+
<Folder Include="Shared\" />
40+
</ItemGroup>
3641
</Project>

0 commit comments

Comments
 (0)