Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #70

Merged
merged 18 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 38 additions & 36 deletions Boolean/Boolean.csproj
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>4043f2b4-1120-4946-b098-003bba4cbbe4</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Discord.Net" Version="3.14.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0-preview.3.24172.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0-preview.3" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>4043f2b4-1120-4946-b098-003bba4cbbe4</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Discord.Net" Version="3.14.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0-preview.3.24172.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0-preview.3.24172.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.3.24172.9" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0-preview.3" />
<PackageReference Include="SkiaSharp" Version="2.88.8" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.8" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
28 changes: 28 additions & 0 deletions Boolean/Modules/BotInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Net.NetworkInformation;
using Boolean.Util;
using Discord;
using Discord.Interactions;
Expand Down Expand Up @@ -70,6 +71,16 @@ public async Task Status()
var startTime = DateTime.UtcNow;
var startCpuUsage = botProcess.TotalProcessorTime;

NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

float startBytesSent = 0;
float startBytesReceived = 0;

foreach (NetworkInterface networkInterface in networkInterfaces) {
startBytesSent += networkInterface.GetIPv4Statistics().BytesSent;
startBytesReceived += networkInterface.GetIPv4Statistics().BytesReceived;
}

await Task.Delay(500);

var endTime = DateTime.UtcNow;
Expand All @@ -78,6 +89,20 @@ public async Task Status()
var cpuUsage = (float) (endCpuUsage - startCpuUsage).TotalMilliseconds
/ (float) (Environment.ProcessorCount * (endTime - startTime).TotalMilliseconds);

float endBytesSent = 0;
float endBytesReceived = 0;

foreach (NetworkInterface networkInterface in networkInterfaces) {
endBytesSent += networkInterface.GetIPv4Statistics().BytesSent;
endBytesReceived += networkInterface.GetIPv4Statistics().BytesReceived;
}

float megabytesSentPerSecond = ((endBytesSent - startBytesSent) / (float) Math.Pow(1024, 2))
/ (float) (endTime - startTime).TotalSeconds;

float megabytesReceivedPerSecond = ((endBytesReceived - startBytesReceived) / (float) Math.Pow(1024, 2))
/ (float) (endTime - startTime).TotalSeconds;

var embed = new EmbedBuilder
{
Title = "Bot Status",
Expand All @@ -89,6 +114,9 @@ public async Task Status()
embed
.AddField("RAM", $"`{Math.Round(ramUsageGb, 2)} GB`", true)
.AddField("CPU Usage", $"`{Math.Round(cpuUsage * 100, 2)}%`", true)
.AddField("** **", "** **") // Empty line to display the following fields in a separate row
.AddField("MB/S Sent", $"`{Math.Round(megabytesSentPerSecond, 2)} MB/S`", true)
.AddField("MB/S Received", $"`{Math.Round(megabytesReceivedPerSecond, 2)} MB/S`", true)
.AddField("Up Time", $"{uptime.Days} days, {uptime.Hours} hours, {uptime.Minutes} minutes, {uptime.Seconds} seconds", false);

await RespondAsync(embed: embed.Build(), ephemeral: true);
Expand Down
74 changes: 56 additions & 18 deletions Boolean/Modules/FunUtils.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
using Boolean.Util;
using Discord;
using Discord.Interactions;

namespace Boolean;

public class FunUtils : InteractionModuleBase<SocketInteractionContext>
{
[SlashCommand("execute", "Executes a fiendish individual.")]
public async Task Execute(IUser user, string? reason = null)
{
await RespondAsync(embed: new EmbedBuilder
{
Description = $"{user.Mention} has been executed by {Context.User.Mention}"
+ (reason != null ? $"\nReason: `{reason}`" : ""),
Color = EmbedColors.Normal,
}.Build());
}
using Boolean.Util;
using Discord;
using Discord.Interactions;
using SkiaSharp;

namespace Boolean;

public class FunUtils : InteractionModuleBase<SocketInteractionContext>
{
[SlashCommand("execute", "Executes a fiendish individual.")]
public async Task Execute(IUser user, string? reason = null)
{
await RespondAsync(embed: new EmbedBuilder
{
Description = $"{user.Mention} has been executed by {Context.User.Mention}"
+ (reason != null ? $"\nReason: `{reason}`" : ""),
Color = EmbedColors.Normal,
}.Build());
}

[SlashCommand("conatidrake", "Creates the drake preference meme BUT conaticus")]
public async Task Conatidrake(string top, string bottom)
{
try
{
var templateImage = SKImage.FromEncodedData("./images/Conatidrake.jpg");
using (var surface = SKSurface.Create(templateImage.Info))
{
surface.Canvas.DrawImage(templateImage, 0, 0);

var font = new SKPaint
{
TextSize = 50,
IsAntialias = true,
Color = new SKColor(0, 0, 0),
Style = SKPaintStyle.Fill,
};

var width = templateImage.Width;
var height = templateImage.Height;

var topRect = new SKRect(width / 2, 0, width, height / 2);
var bottomRect = new SKRect(width / 2, height / 2, width, height);

Text.DrawTextBox(surface.Canvas, top, topRect, font);
Text.DrawTextBox(surface.Canvas, bottom, bottomRect, font);

var stream = surface.Snapshot().Encode().AsStream();
await Context.Channel.SendFileAsync(stream, "conatidrake.png");
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
145 changes: 73 additions & 72 deletions Boolean/Program.cs
Original file line number Diff line number Diff line change
@@ -1,73 +1,74 @@
using System.Reflection;
using Discord;
using Discord.Interactions;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Boolean;

class Program
{
private static ServiceProvider _serviceProvider;
private static DiscordSocketClient _client;

public static async Task Main()
{
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
Config config = builder.Configuration.Get<Config>()
?? throw new Exception("Failed to load valid config from appsettings.json, please refer to the README.md for instructions.");

builder.Services
.AddDbContext<DataContext>(options => options.UseNpgsql(config.GetConnectionString()));

// Only start the bot outside of design time (avoids app running during dotnet ef commands)
if (EF.IsDesignTime) {
_serviceProvider = builder.Services.BuildServiceProvider();
goto buildApp;
}

_client = new DiscordSocketClient(new DiscordSocketConfig
{
GatewayIntents = GatewayIntents.All,
UseInteractionSnowflakeDate = false, // Prevents a funny from happening when your OS clock is out of sync
MessageCacheSize = 100,
});

var interactionService = new InteractionService(_client.Rest);

builder.Services
.AddSingleton(interactionService)
.AddSingleton(_client)
.AddSingleton(config)
.AddSingleton<EventHandlers>();

_serviceProvider = builder.Services.BuildServiceProvider();

await _client.LoginAsync(TokenType.Bot, config.DiscordToken);
await _client.StartAsync();

await interactionService.AddModulesAsync(Assembly.GetEntryAssembly(), _serviceProvider);
AttachEventHandlers();

buildApp:
IHost app = builder.Build();
await app.RunAsync();
}

private static void AttachEventHandlers()
{
var eventHandlers = _serviceProvider.GetRequiredService<EventHandlers>();

_client.Log += eventHandlers.LogMessage;
_client.Ready += eventHandlers.Ready;
_client.InteractionCreated += eventHandlers.InteractionCreated;
_client.JoinedGuild += eventHandlers.GuildCreate;
_client.ButtonExecuted += eventHandlers.ButtonExecuted;
_client.ReactionAdded += eventHandlers.ReactionAdded;
_client.ReactionRemoved += eventHandlers.ReactionRemoved;
_client.UserJoined += eventHandlers.UserJoined;
}
using System.Reflection;
using Discord;
using Discord.Interactions;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Boolean;

class Program
{
private static ServiceProvider _serviceProvider;
private static DiscordSocketClient _client;

public static async Task Main()
{
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
Config config = builder.Configuration.Get<Config>()
?? throw new Exception("Failed to load valid config from appsettings.json, please refer to the README.md for instructions.");

builder.Services
.AddDbContext<DataContext>(options => options.UseNpgsql(config.GetConnectionString()));

// Only start the bot outside of design time (avoids app running during dotnet ef commands)
if (EF.IsDesignTime)
{
_serviceProvider = builder.Services.BuildServiceProvider();
goto buildApp;
}

_client = new DiscordSocketClient(new DiscordSocketConfig
{
GatewayIntents = GatewayIntents.All,
UseInteractionSnowflakeDate = false, // Prevents a funny from happening when your OS clock is out of sync
MessageCacheSize = 100,
});

var interactionService = new InteractionService(_client.Rest);

builder.Services
.AddSingleton(interactionService)
.AddSingleton(_client)
.AddSingleton(config)
.AddSingleton<EventHandlers>();

_serviceProvider = builder.Services.BuildServiceProvider();

await _client.LoginAsync(TokenType.Bot, config.DiscordToken);
await _client.StartAsync();

await interactionService.AddModulesAsync(Assembly.GetEntryAssembly(), _serviceProvider);
AttachEventHandlers();

buildApp:
IHost app = builder.Build();
await app.RunAsync();
}

private static void AttachEventHandlers()
{
var eventHandlers = _serviceProvider.GetRequiredService<EventHandlers>();

_client.Log += eventHandlers.LogMessage;
_client.Ready += eventHandlers.Ready;
_client.InteractionCreated += eventHandlers.InteractionCreated;
_client.JoinedGuild += eventHandlers.GuildCreate;
_client.ButtonExecuted += eventHandlers.ButtonExecuted;
_client.ReactionAdded += eventHandlers.ReactionAdded;
_client.ReactionRemoved += eventHandlers.ReactionRemoved;
_client.UserJoined += eventHandlers.UserJoined;
}
}
25 changes: 25 additions & 0 deletions Boolean/Utils/Drawing/Text.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using SkiaSharp;

public static class Text
{
public static void DrawTextBox(SKCanvas canvas, string text, SKRect rect, SKPaint paint)
{
var spaceWidth = paint.MeasureText(" ");
var wordX = rect.Left;
var wordY = rect.Top + paint.TextSize;

foreach (var word in text.Split(' '))
{
var wordWidth = paint.MeasureText(word);

if (wordWidth > rect.Right - wordX)
{
wordY += paint.FontSpacing;
wordX = rect.Left;
}

canvas.DrawText(word, wordX, wordY, paint);
wordX += wordWidth + spaceWidth;
}
}
}
Loading
Loading