Skip to content
This repository was archived by the owner on Mar 26, 2025. It is now read-only.

Commit 21eceea

Browse files
authored
Merge pull request #11 from StoreDev/slash-commands
Migrate to slash commands
2 parents 0c33cc2 + f77139a commit 21eceea

File tree

6 files changed

+254
-394
lines changed

6 files changed

+254
-394
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- name: Setup .NET Core
1313
uses: actions/setup-dotnet@v1
1414
with:
15-
dotnet-version: '3.1.x'
15+
dotnet-version: '6.0.x'
1616
- name: Install dependencies
1717
run: dotnet restore
1818
- name: Build
@@ -21,13 +21,13 @@ jobs:
2121
uses: actions/upload-artifact@v2
2222
with:
2323
name: storebot-${{ github.sha }}.zip
24-
path: bin/Release/netcoreapp3.1
24+
path: bin/Release/net6.0
2525
- name: Get the version tag
2626
id: get_tag
2727
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
2828
- name: Generate zip for release
2929
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
30-
run: zip -j Storebot-${{ steps.get_tag.outputs.VERSION }}.zip ./bin/Release/netcoreapp3.1/* ./README.md ./config.json
30+
run: zip -j Storebot-${{ steps.get_tag.outputs.VERSION }}.zip ./bin/Release/net6.0/* ./README.md ./config.json
3131
- name: create release
3232
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
3333
id: create_release

AuthCommands.cs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
using DSharpPlus.CommandsNext;
2-
using DSharpPlus.CommandsNext.Attributes;
1+
using DSharpPlus;
2+
using DSharpPlus.Entities;
3+
using DSharpPlus.SlashCommands;
34
using System;
45
using System.Collections.Generic;
56
using System.Linq;
@@ -9,61 +10,62 @@
910
using XboxWebApi.Authentication.Model;
1011
using XboxWebApi.Common;
1112
using System.IO;
12-
using DSharpPlus.Entities;
1313
using System.Net.Security;
1414

15+
1516
namespace StoreBot
1617
{
17-
public class AuthCommands : BaseCommandModule
18+
public class AuthCommands : ApplicationCommandModule
19+
{
20+
[SlashCommand("SubmitToken", "Provide a MSA token to allow for flighted queries, DM ONLY")]
21+
public async Task IngestAuthToken(InteractionContext ctx, [Option("token","The MSA token / Xtoken to ingest")] string token)
1822
{
19-
[Command("submittoken"), Description("Provide a MSA token to allow for flighted queries, DM ONLY")]
20-
public async Task IngestAuthToken(CommandContext cct, [Description("MSA/Xtoken")] string token)
23+
if (ctx.Guild != null)
2124
{
22-
if (cct.Guild != null)
23-
{
24-
var lastmessage = await cct.Channel.GetMessagesAsync(1);
25-
await cct.Channel.DeleteMessageAsync(lastmessage[0]);
26-
await cct.RespondAsync($"{cct.Message.Author.Mention} you must submit your token via a DM to avoid account takeover. Your token may have been exposed, an account relog is recommended.");
27-
return;
28-
}
29-
ulong DiscordAuthorID = cct.User.Id;
30-
if (Program.TokenDictionary.ContainsKey(DiscordAuthorID))
31-
{
32-
Program.TokenDictionary.Remove(DiscordAuthorID);
33-
Program.TokenDictionary.Add(DiscordAuthorID, token);
34-
await cct.RespondAsync("Your token has been updated.");
35-
return;
36-
37-
}
38-
Program.TokenDictionary.Add(DiscordAuthorID, token);
39-
await cct.RespondAsync($"Your token has been ingested. It will be used for all future commands coming from you. (Discord ID: {DiscordAuthorID})"); ;
25+
var lastmessage = await ctx.Channel.GetMessagesAsync(1);
26+
await ctx.Channel.DeleteMessageAsync(lastmessage[0]);
27+
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent($"{ctx.User.Mention} you must submit your token via a DM to avoid account takeover. Your token may have been exposed, an account relog is recommended."));
28+
return;
4029
}
41-
[Command("GenerateTokens"), Description("Export tokens from authentication url, run the command with no arguments for more info")]
42-
public async Task GenerateTokens(CommandContext cct, [Description("Authentication URL")] Uri tokenuri=null)
30+
ulong DiscordAuthorID = ctx.User.Id;
31+
if (Program.TokenDictionary.ContainsKey(DiscordAuthorID))
4332
{
33+
Program.TokenDictionary.Remove(DiscordAuthorID);
34+
Program.TokenDictionary.Add(DiscordAuthorID, token);
35+
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent($"Your token has been updated."));
36+
return;
37+
38+
}
39+
Program.TokenDictionary.Add(DiscordAuthorID, token);
40+
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent($"Your token has been ingested. It will be used for all future commands coming from you. (Discord ID: {DiscordAuthorID})"));
41+
}
42+
43+
[SlashCommand("GenerateTokens", "Export tokens from authentication url, run the command with no arguments for more info")]
44+
public async Task GenerateTokens(InteractionContext ctx, [Option("TokenUrl","Authentication URL. Leave this blank to get usage instructions for this command.")] string tokenuri = null)
45+
{
4446

45-
if (cct.Guild != null)
47+
if (ctx.Guild != null)
4648
{
47-
var lastmessage = await cct.Channel.GetMessagesAsync(1);
48-
await cct.Channel.DeleteMessageAsync(lastmessage[0]);
49-
await cct.RespondAsync($"{cct.Message.Author.Mention} you must submit your token via a DM to avoid account takeover. Your token may have been exposed, an account relog is recommended.");
49+
var lastmessage = await ctx.Channel.GetMessagesAsync(1);
50+
await ctx.Channel.DeleteMessageAsync(lastmessage[0]);
51+
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent($"{ctx.User.Mention} you must submit your token via a DM to avoid account takeover. Your token may have been exposed, an account relog is recommended."));
5052
return;
5153
}
5254

5355
if (tokenuri == null)
5456
{
5557
var inforesponse = new DiscordEmbedBuilder()
5658
{
57-
Title="Advanced info",
59+
Title = "Advanced info",
5860
Description = "The tokenuri parameter is the response from: \nhttps://login.live.com/oauth20_authorize.srf?display=touch&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL&redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf&locale=en&response_type=token&client_id=0000000048093EE3, the full command should look something like:\n`generatetokens https://login.live.com/oauth20_desktop.srf?...access_token=...&refresh_token=...`"
5961
};
6062
inforesponse.Build();
61-
await cct.RespondAsync(null,false,inforesponse);
63+
await ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, new DiscordInteractionResponseBuilder().AddEmbed(inforesponse.Build()));
6264
return;
6365
}
6466
try
6567
{
66-
await cct.TriggerTypingAsync();
68+
await ctx.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource);
6769
WindowsLiveResponse response = AuthenticationService.ParseWindowsLiveResponse(tokenuri.ToString());
6870
AuthenticationService authenticator = new AuthenticationService(response);
6971
//get user token
@@ -75,13 +77,14 @@ public async Task GenerateTokens(CommandContext cct, [Description("Authenticatio
7577
//export json
7678
Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(AuthenticationService.DumpToJson(authenticator)));
7779
//respond with tokens
78-
await cct.RespondWithFileAsync("tokens.json", stream);
80+
var msg = await new DiscordMessageBuilder().WithFiles(new Dictionary<string, Stream>() { { "tokens.json", stream} }).SendAsync(ctx.Channel);
81+
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent("Generated tokens successfully:"));
7982
}
8083
catch
8184
{
82-
await cct.RespondAsync("An unknown authentication error occured");
85+
await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent("An unknown authentication error occured"));
8386
}
8487
return;
85-
}
8688
}
8789
}
90+
}

Enums.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using DSharpPlus.SlashCommands;
7+
8+
namespace StoreBot
9+
{
10+
public class Enums
11+
{
12+
public enum DeviceFamily
13+
{
14+
[ChoiceName("Desktop")]
15+
Desktop,
16+
[ChoiceName("Mobile")]
17+
Mobile,
18+
[ChoiceName("Xbox")]
19+
Xbox,
20+
[ChoiceName("Server Core")]
21+
ServerCore,
22+
[ChoiceName("Iot Core")]
23+
IotCore,
24+
[ChoiceName("HoloLens")]
25+
HoloLens,
26+
[ChoiceName("Andromeda")]
27+
Andromeda,
28+
[ChoiceName("Universal")]
29+
Universal,
30+
[ChoiceName("Windows Core OS")]
31+
WCOS
32+
}
33+
34+
public enum DCatEndpoint
35+
{
36+
[ChoiceName("Production")]
37+
Production,
38+
[ChoiceName("Internal")]
39+
Int,
40+
[ChoiceName("Xbox")]
41+
Xbox,
42+
[ChoiceName("Xbox Internal")]
43+
XboxInt,
44+
[ChoiceName("Dev")]
45+
Dev,
46+
[ChoiceName("OneP")]
47+
OneP,
48+
[ChoiceName("OneP Internal")]
49+
OnePInt
50+
}
51+
}
52+
}

Program.cs

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
using DSharpPlus;
2-
using DSharpPlus.CommandsNext;
3-
using DSharpPlus.CommandsNext.Exceptions;
42
using DSharpPlus.Entities;
53
using DSharpPlus.EventArgs;
6-
using DSharpPlus.Interactivity;
4+
using DSharpPlus.SlashCommands;
75
using Newtonsoft.Json;
6+
using Microsoft.Extensions.Logging;
87
using System;
98
using System.Collections;
109
using System.Collections.Generic;
@@ -25,33 +24,33 @@ public struct ConfigJson
2524
public string Token { get; private set; }
2625
}
2726

28-
public static Task Client_Ready(ReadyEventArgs e)
27+
public static Task Client_Ready(DiscordClient _, ReadyEventArgs e)
2928
{
30-
e.Client.DebugLogger.LogMessage(LogLevel.Info, "StoreBot", "Client is ready to process events.", DateTime.Now);
29+
_.Logger.LogInformation(new EventId(1337,"StoreBot") , "Client is ready to process events.");
3130
return Task.CompletedTask;
3231
}
3332

34-
private static Task Client_GuildAvailable(GuildCreateEventArgs e)
33+
private static Task Client_GuildAvailable(DiscordClient _, GuildCreateEventArgs e)
3534
{
36-
e.Client.DebugLogger.LogMessage(LogLevel.Info, "StoreBot", $"Server available: {e.Guild.Name}", DateTime.Now);
35+
_.Logger.LogInformation(new EventId(1337,"StoreBot") , $"Server available: {e.Guild.Name}");
3736
return Task.CompletedTask;
3837
}
3938

40-
private static Task Client_ClientError(ClientErrorEventArgs e)
39+
private static Task Client_ClientError(DiscordClient _, ClientErrorEventArgs e)
4140
{
42-
e.Client.DebugLogger.LogMessage(LogLevel.Error, "StoreBot", $"Exception occured: {e.Exception.GetType()}: {e.Exception.Message}", DateTime.Now);
41+
_.Logger.LogInformation(new EventId(1337,"StoreBot") , $"Exception occured: {e.Exception.GetType()}: {e.Exception.Message}");
4342
return Task.CompletedTask;
4443
}
4544

46-
private static Task Commands_CommandExecuted(CommandExecutionEventArgs e)
45+
private static Task Slash_SlashCommandErrored(SlashCommandsExtension sender, DSharpPlus.SlashCommands.EventArgs.SlashCommandErrorEventArgs e)
4746
{
48-
e.Context.Client.DebugLogger.LogMessage(LogLevel.Info, "StoreBot", $"{e.Context.User.Username}:{e.Context.User.Id.ToString()} ran command '{e.Command.QualifiedName}'", DateTime.Now);
49-
return Task.CompletedTask;
47+
sender.Client.Logger.LogInformation(new EventId(1337, "StoreBot"), $"{e.Context.User.Username} tried executing '{e.Context?.CommandName ?? "<unknown command>"}' but it errored: {e.Exception.GetType()}: {e.Exception.Message ?? "<no message>"}");
48+
throw new NotImplementedException();
5049
}
5150

52-
private static Task Commands_CommandErrored(CommandErrorEventArgs e)
51+
private static Task Slash_SlashCommandExecuted(SlashCommandsExtension sender, DSharpPlus.SlashCommands.EventArgs.SlashCommandExecutedEventArgs e)
5352
{
54-
e.Context.Client.DebugLogger.LogMessage(LogLevel.Error, "StoreBot", $"{e.Context.User.Username} tried executing '{e.Command?.QualifiedName ?? "<unknown command>"}' but it errored: {e.Exception.GetType()}: {e.Exception.Message ?? "<no message>"}", DateTime.Now);
53+
sender.Client.Logger.LogInformation(new EventId(1337, "StoreBot"), $"{e.Context.User.Username}:{e.Context.User.Id.ToString()} ran command '{e.Context.CommandName}'");
5554
return Task.CompletedTask;
5655
}
5756

@@ -65,8 +64,7 @@ public static async Task<DiscordConfiguration> LoadConfig()
6564
Token = token,
6665
TokenType = TokenType.Bot,
6766
AutoReconnect = true,
68-
LogLevel = LogLevel.Info,
69-
UseInternalLogHandler = true
67+
MinimumLogLevel = LogLevel.Information
7068
};
7169
return configenv;
7270
}
@@ -84,8 +82,7 @@ public static async Task<DiscordConfiguration> LoadConfig()
8482
Token = cfgjson.Token,
8583
TokenType = TokenType.Bot,
8684
AutoReconnect = true,
87-
LogLevel = LogLevel.Info,
88-
UseInternalLogHandler = true
85+
MinimumLogLevel= LogLevel.Information
8986
};
9087
return config;
9188
}
@@ -97,30 +94,16 @@ public static async Task Main(string[] args)
9794
client.Ready += Client_Ready;
9895
client.GuildAvailable += Client_GuildAvailable;
9996
client.ClientErrored += Client_ClientError;
100-
client.UseInteractivity(new InteractivityConfiguration
101-
{
102-
Timeout = TimeSpan.FromMinutes(2)
103-
});
104-
105-
var ccfg = new CommandsNextConfiguration
106-
{
10797

108-
// enable responding in direct messages
109-
EnableDms = true,
98+
var slash = client.UseSlashCommands();
99+
slash.RegisterCommands<StoreCommands>();
100+
slash.RegisterCommands<AuthCommands>();
101+
slash.SlashCommandErrored += Slash_SlashCommandErrored;
102+
slash.SlashCommandExecuted += Slash_SlashCommandExecuted;
110103

111-
// enable mentioning the bot as a command prefix
112-
EnableMentionPrefix = true
113-
};
114-
115-
var Commands = client.UseCommandsNext(ccfg);
116-
Commands.CommandErrored += Commands_CommandErrored;
117-
Commands.CommandExecuted += Commands_CommandExecuted;
118-
Commands.RegisterCommands<StoreCommands>();
119-
Commands.RegisterCommands<AuthCommands>();
120-
await client.ConnectAsync(new DiscordActivity("DisplayCatalog", ActivityType.Watching), UserStatus.Online);
104+
await client.ConnectAsync(new DiscordActivity
105+
("DisplayCatalog", ActivityType.Watching), UserStatus.Online);
121106
await Task.Delay(-1);
122107
}
123-
124-
125108
}
126109
}

StoreBot.csproj

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<TargetFramework>net6.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="DSharpPlus" Version="4.0.0-nightly-00709" />
10-
<PackageReference Include="DSharpPlus.CommandsNext" Version="4.0.0-nightly-00709" />
11-
<PackageReference Include="DSharpPlus.Interactivity" Version="4.0.0-nightly-00709" />
9+
<PackageReference Include="DSharpPlus" Version="4.2.0" />
10+
<PackageReference Include="DSharpPlus.SlashCommands" Version="4.2.0" />
1211
<PackageReference Include="OpenXbox.XboxWebApi" Version="0.3.0" />
1312
<PackageReference Include="StoreLib" Version="1.2.1" />
1413
</ItemGroup>
1514

15+
<ItemGroup>
16+
<None Update="config.json">
17+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
18+
</None>
19+
</ItemGroup>
20+
1621
</Project>

0 commit comments

Comments
 (0)