Skip to content

Instantly share code, notes, and snippets.

@Hantick
Created May 31, 2020 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hantick/f0b3e126117004fbab56f782ba16934e to your computer and use it in GitHub Desktop.
Save Hantick/f0b3e126117004fbab56f782ba16934e to your computer and use it in GitHub Desktop.
Vincenzo
using Serilog;
using System;
using System.Threading;
using System.Threading.Tasks;
using VincenzoBot.Main.Models;
namespace VincenzoBot.Main
{
public class DiscordBot
{
private CancellationTokenSource Source { get; set; }
public bool IsRunning { get; private set; }
private readonly DiscordConnection _discordConnection;
private readonly DiscordBotConfig _config;
public DiscordBot(DiscordConnection discordConnection, DiscordBotConfig config)
{
_discordConnection = discordConnection;
_config = config;
}
public async Task StartAsync()
{
Source = new CancellationTokenSource();
try
{
IsRunning = true;
await _discordConnection.RunAsync(_config, Source.Token);
}
catch (OperationCanceledException ocex)
{
if (!Source.IsCancellationRequested)
Log.Error(ocex.Message);
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
finally
{
IsRunning = false;
}
}
public void Stop()
{
if (Source != null)
Source.Cancel();
}
public void Stop(int delay)
{
if (Source != null)
Source.CancelAfter(delay);
}
public void Stop(TimeSpan delay)
{
if (Source != null)
Source.CancelAfter(delay);
}
public async Task Restart()
{
Stop();
await StartAsync();
}
}
}
using Discord;
using Discord.WebSocket;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using System;
using System.Threading;
using System.Threading.Tasks;
using VincenzoBot.Main.Discord;
using VincenzoBot.Main.Discord.Services;
using VincenzoBot.Main.Discord.Services.Handlers;
using VincenzoBot.Main.Models;
using VincenzoBot.Main.User;
namespace VincenzoBot.Main
{
public class DiscordConnection
{
private readonly DiscordLogger _discordLogger;
private DiscordSocketClient _client;
private readonly IServiceProvider _serviceProvider;
private readonly UserAccountService _userAccountService;
public DiscordConnection(DiscordLogger discordLogger, IServiceProvider serviceProvider, UserAccountService userAccountService)
{
_discordLogger = discordLogger;
_serviceProvider = serviceProvider;
_userAccountService = userAccountService;
}
public async Task RunAsync(DiscordBotConfig config, CancellationToken token = default)
{
try
{
var discordSocketConfig = new DiscordSocketConfig()
{
LogLevel = LogSeverity.Info,
AlwaysDownloadUsers = true
};
_client = new DiscordSocketClient(discordSocketConfig) { };
await (_client as BaseSocketClient).LoginAsync(TokenType.Bot, config.Token);
_client.Log += _discordLogger.Log;
_client.Ready += Ready;
_client.GuildMembersDownloaded += GuildMembersDownloaded;
_client.UserJoined += UserJoinedToGuild;
await _client.StartAsync();
await Task.Delay(-1, token);
}
catch (OperationCanceledException ocex)
{
if (!token.IsCancellationRequested)
await LogRunException(ocex);
}
catch (Exception ex)
{
await LogRunException(ex);
}
finally
{
if (_client != null)
{
await _client.LogoutAsync();
_client.Dispose();
}
}
}
private Task UserJoinedToGuild(SocketGuildUser arg)
{
_client.DownloadUsersAsync(_client.Guilds);
_userAccountService.CreateUserAccount(arg);
return Task.CompletedTask;
}
private Task GuildMembersDownloaded(SocketGuild arg)
{
Log.Information("Downloaded all guild members");
_userAccountService.SyncAccounts(arg.Users);
return Task.CompletedTask;
}
private async Task Ready()
{
var punishmetService = _serviceProvider.GetRequiredService<UserPunishmetsService>();//TODO better
var messageHandler = _serviceProvider.GetRequiredService<MessageHandlerService>();
await messageHandler.InitializeAsync(_client);
_client.MessageReceived += messageHandler.HandleMessageAsync;
var userEventsHandler = _serviceProvider.GetRequiredService<UserEventsHandlerService>();
_client.UserBanned += userEventsHandler.HandleUserBanned;
}
private async Task LogRunException(Exception ex) => await _discordLogger.Log(new LogMessage(LogSeverity.Critical, typeof(DiscordConnection).GetMethod("RunAsync").Name, "Something went wrong while running the bot. Here is attached an exception", ex));
}
}
using Serilog;
using System;
using VincenzoBot.Main.Logging;
namespace VincenzoBot.Main.Main
{
public static class Program
{
private static void Main()
{
Console.Title = "Vincenzo Discord Bot";
Log.Logger = SeriLogger.GetLoggerConfig();
Console.WriteLine("To quit the program, double click 'q'");
Bot bot = new Bot(StartupServiceProvider.BuildServiceProvider());
bot.DiscordBot.StartAsync();
HandleInput(bot);
}
private static void HandleInput(Bot bot)
{
while (true)
{
var choice = Console.ReadKey().KeyChar;
switch (choice)
{
case 'q':
{
ClearCurrentConsoleLine();
Console.WriteLine("Exit program (q)?");
var choice2 = Console.ReadKey().KeyChar;
switch (choice2)
{
case 'q':
ClearCurrentConsoleLine();
bot.DiscordBot.Stop();
break;
default:
ClearCurrentConsoleLine();
break;
}
break;
}
default:
ClearCurrentConsoleLine();
break;
}
}
}
public static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment