Skip to content

Commit

Permalink
Fix DeepSource issues
Browse files Browse the repository at this point in the history
Fixed issues:
- Method has non-nullable return type but returns null CS-W1029 (ConfigManager.cs)
- Found the usage of DateTime.Now that relies on system-specific information CS-W1091 (Program.cs)
- Use File Scoped namespaces instead of typical namespaces CS-R1062 (CommandManager.cs, ConfigManager.cs)
- Classes and structs should be declared within a namespace CS-W1061 (Program.cs)
- Fields initialized only in constructors can be made readonly CS-R1137 (CommandManager.cs)
- Abrupt application exit CS-W1005 (ConfigManager.cs)
- #2 Methods that deal with async should have their names suffixed with Async CS-R1073 (CommandManager.cs, Program.cs)
- Also moved QuickEdit.Config namespace to QuickEdit, so Config is now reference by QuickEdit.Config instead of QuickEdit.Config.Config (ConfigManager.cs)
  • Loading branch information
HEJOK254 committed Jun 15, 2024
1 parent 3578df4 commit c58b094
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 85 deletions.
102 changes: 50 additions & 52 deletions Commands/CommandManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Discord;
using Discord;
using Discord.WebSocket;
using System;
using System.Collections.Generic;
Expand All @@ -7,69 +7,67 @@
using System.Text;
using System.Threading.Tasks;

namespace QuickEdit.Commands
namespace QuickEdit.Commands;
public class CommandManager
{
public class CommandManager
{
private DiscordSocketClient _client = Program.client;
private readonly DiscordSocketClient _client = Program.client;

// Macros for interaction context types
private static readonly InteractionContextType[] interactionContextAll = new InteractionContextType[] { InteractionContextType.PrivateChannel, InteractionContextType.Guild, InteractionContextType.BotDm };
private static readonly InteractionContextType[] interactionContextUser = new InteractionContextType[] { InteractionContextType.PrivateChannel, InteractionContextType.Guild };
// Macros for interaction context types
private static readonly InteractionContextType[] interactionContextAll = new InteractionContextType[] { InteractionContextType.PrivateChannel, InteractionContextType.Guild, InteractionContextType.BotDm };
private static readonly InteractionContextType[] interactionContextUser = new InteractionContextType[] { InteractionContextType.PrivateChannel, InteractionContextType.Guild };

#region Command List
List<SlashCommandBuilder> slashCommandBuilders = new List<SlashCommandBuilder>() {
new SlashCommandBuilder()
.WithName("test")
.WithDescription("Test command.")
.WithIntegrationTypes(ApplicationIntegrationType.UserInstall)
.WithContextTypes(interactionContextAll),
};
#endregion
#region Command List
List<SlashCommandBuilder> slashCommandBuilders = new List<SlashCommandBuilder>() {
new SlashCommandBuilder()
.WithName("test")
.WithDescription("Test command.")
.WithIntegrationTypes(ApplicationIntegrationType.UserInstall)
.WithContextTypes(interactionContextAll),
};
#endregion

public async Task Init()
{
// Build and register commands
var builtCommands = BulkBuildCommands(slashCommandBuilders);
await RegisterCommands(builtCommands);
public async Task InitAsync()
{
// Build and register commands
var builtCommands = BulkBuildCommands(slashCommandBuilders);
await RegisterCommandsAsync(builtCommands);

_client.SlashCommandExecuted += SlashCommandHandler;
_client.SlashCommandExecuted += SlashCommandHandlerAsync;
}

private List<SlashCommandProperties> BulkBuildCommands(List<SlashCommandBuilder> commandBuilders) {
var builtCommands = new List<SlashCommandProperties>();
foreach (var commandBuilder in commandBuilders) {
builtCommands.Add(commandBuilder.Build());
}

private List<SlashCommandProperties> BulkBuildCommands(List<SlashCommandBuilder> commandBuilders) {
var builtCommands = new List<SlashCommandProperties>();
foreach (var commandBuilder in commandBuilders) {
builtCommands.Add(commandBuilder.Build());
}
return builtCommands;
}

return builtCommands;
public async Task RegisterCommandsAsync(List<SlashCommandProperties> slashCommands) {
try {
await _client.BulkOverwriteGlobalApplicationCommandsAsync(slashCommands.ToArray());
await Program.LogAsync("CommandManager", "Successfully registered slash commands.");
}

public async Task RegisterCommands(List<SlashCommandProperties> slashCommands) {
try {
await _client.BulkOverwriteGlobalApplicationCommandsAsync(slashCommands.ToArray());
await Program.Log("CommandManager", "Successfully registered slash commands.");
}
catch {
await Program.Log("CommandManager", "Failed to register slash commands.", LogSeverity.Critical);
return;
}
catch {
await Program.LogAsync("CommandManager", "Failed to register slash commands.", LogSeverity.Critical);
return;
}
}

private async Task SlashCommandHandler(SocketSlashCommand command)
private async Task SlashCommandHandlerAsync(SocketSlashCommand command)
{
switch (command.Data.Name)
{
switch (command.Data.Name)
{
case "test":
await command.RespondAsync("Test command executed!");
break;
case "test":
await command.RespondAsync("Test command executed!");
break;

// In case the command is not recognized by the bot
default:
await command.RespondAsync("An error occurred with the command you tried to execute", ephemeral: true);
await Program.Log("CommandManager", "Failed to execute slash command.", LogSeverity.Error);
break;
}
// In case the command is not recognized by the bot
default:
await command.RespondAsync("An error occurred with the command you tried to execute", ephemeral: true);
await Program.LogAsync("CommandManager", "Failed to execute slash command.", LogSeverity.Error);
break;
}
}
}
}
43 changes: 20 additions & 23 deletions ConfigManager.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
using Discord;
using Newtonsoft.Json;

namespace QuickEdit.Config
namespace QuickEdit;
public class Config
{
public class Config
{
public required string token;
public ulong logChannel;
public ulong guildID;
public ActivityType statusType;
public string status = string.Empty;
public bool debug = false;
public required string token;
public ulong logChannel;
public ulong guildID;
public ActivityType statusType;
public string status = string.Empty;
public bool debug = false;

public static Config GetConfig()
public static Config? GetConfig()
{
string path = "./config.json";
if (!File.Exists(path))
{
string path = "./config.json";
if (!File.Exists(path))
{
Program.Log("Config", $"Config file not found at: {path}", LogSeverity.Critical);
Environment.Exit(1);
}
Program.LogAsync("Config", $"Config file not found at: {path}", LogSeverity.Critical);
return null;
}

try {
return JsonConvert.DeserializeObject<Config>(File.ReadAllText(path))!;
} catch {
Program.Log("Config" , "Failed to parse config file.", LogSeverity.Critical);
Environment.Exit(1);
return null;
}
try {
return JsonConvert.DeserializeObject<Config>(File.ReadAllText(path))!;
} catch {
Program.LogAsync("Config" , "Failed to parse config file.", LogSeverity.Critical);
return null;
}
}
}
23 changes: 13 additions & 10 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@
using Discord.WebSocket;
using QuickEdit;
using QuickEdit.Commands;
using QuickEdit.Config;

namespace QuickEdit;
class Program
{
public static DiscordSocketClient client;

Check warning on line 9 in Program.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'client' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 9 in Program.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'client' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
public static Config config = Config.GetConfig();
public static Config? config = Config.GetConfig();

public static Task Main(string[] args) => new Program().MainAsync();

public async Task MainAsync()
{
// If the config is null, we can't continue as the bot won't have a token to login with
if (config == null) return;

client = new DiscordSocketClient();

client.Log += Log;
client.Ready += OnReady;
client.Log += LogAsync;
client.Ready += OnReadyAsync;

await client.LoginAsync(TokenType.Bot, config.token);
await client.StartAsync();
Expand All @@ -31,21 +34,21 @@ public async Task MainAsync()
await Task.Delay(-1);
}

private async Task OnReady()
private async Task OnReadyAsync()
{
await new CommandManager().Init();
await new CommandManager().InitAsync();
}

public Task Log(LogMessage message)
public Task LogAsync(LogMessage message)
{
string msg = $"[{DateTime.Now.ToString("HH.mm.ss")}] {message.Source}: {message.Message}";
string msg = $"[{DateTime.UtcNow.ToString("HH.mm.ss")}] {message.Source}: {message.Message}";
Console.WriteLine(msg + " " + message.Exception);
return Task.CompletedTask;
}

public static Task Log(string source, string message, LogSeverity severity = LogSeverity.Info)
public static Task LogAsync(string source, string message, LogSeverity severity = LogSeverity.Info)
{
string msg = $"[{DateTime.Now.ToString("HH.mm.ss")}] {source}: {message}";
string msg = $"[{DateTime.UtcNow.ToString("HH.mm.ss")}] {source}: {message}";

// Change color based on severity
switch (severity)
Expand Down

0 comments on commit c58b094

Please sign in to comment.