diff options
author | Rory& <root@rory.gay> | 2024-06-03 20:19:21 +0200 |
---|---|---|
committer | Rory& <root@rory.gay> | 2024-06-03 20:19:21 +0200 |
commit | 49eba40d2bc6a98553e57e6f9b8496ff649147a8 (patch) | |
tree | bf79603c455ef65b7cfa349cbce285cedd8bf53a /Jenny | |
download | Jenny-master.tar.xz |
Initial commit HEAD github/master master
Diffstat (limited to 'Jenny')
-rw-r--r-- | Jenny/Commands/ConfigureCommand.cs | 38 | ||||
-rw-r--r-- | Jenny/Commands/ConfigureSubCommands/ControlRoomConfigureSubcommand.cs | 18 | ||||
-rw-r--r-- | Jenny/Commands/ImgCommand.cs | 134 | ||||
-rw-r--r-- | Jenny/Commands/PatCommand.cs | 164 | ||||
-rw-r--r-- | Jenny/Handlers/CommandResultHandler.cs | 40 | ||||
-rw-r--r-- | Jenny/Handlers/InviteHandler.cs | 12 | ||||
-rw-r--r-- | Jenny/Jenny.csproj | 36 | ||||
-rw-r--r-- | Jenny/JennyBot.cs | 32 | ||||
-rw-r--r-- | Jenny/JennyConfiguration.cs | 9 | ||||
-rw-r--r-- | Jenny/Program.cs | 33 | ||||
-rw-r--r-- | Jenny/Properties/launchSettings.json | 26 | ||||
m--------- | Jenny/Resources | 0 | ||||
-rw-r--r-- | Jenny/appsettings.Development.json | 24 | ||||
-rw-r--r-- | Jenny/appsettings.json | 9 |
14 files changed, 575 insertions, 0 deletions
diff --git a/Jenny/Commands/ConfigureCommand.cs b/Jenny/Commands/ConfigureCommand.cs new file mode 100644 index 0000000..efd3417 --- /dev/null +++ b/Jenny/Commands/ConfigureCommand.cs @@ -0,0 +1,38 @@ +using System.Text; +using LibMatrix.EventTypes.Spec; +using LibMatrix.Utilities.Bot.Commands; +using LibMatrix.Utilities.Bot.Interfaces; +using Microsoft.Extensions.DependencyInjection; + +namespace Jenny.Commands; + +public class ConfigureCommand(IServiceProvider svcs) : ICommandGroup { + public string Name { get; } = "configure"; + public string[]? Aliases { get; } = ["config", "cfg"]; + public string Description { get; } + public bool Unlisted { get; } = true; + + public async Task Invoke(CommandContext ctx) { + var commands = svcs.GetServices<ICommand>().Where(x => x.GetType().IsAssignableTo(typeof(ICommand<>).MakeGenericType(GetType()))).ToList(); + + if (ctx.Args.Length == 0) { + await ctx.Room.SendMessageEventAsync(HelpCommand.GenerateCommandList(commands).Build()); + } + else { + var subcommand = ctx.Args[0]; + var command = commands.FirstOrDefault(x => x.Name == subcommand || x.Aliases?.Contains(subcommand) == true); + if (command == null) { + await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent("m.notice", "Unknown subcommand")); + return; + } + + await command.Invoke(new CommandContext { + Room = ctx.Room, + MessageEvent = ctx.MessageEvent, + CommandName = ctx.CommandName, + Args = ctx.Args.Skip(1).ToArray(), + Homeserver = ctx.Homeserver + }); + } + } +} \ No newline at end of file diff --git a/Jenny/Commands/ConfigureSubCommands/ControlRoomConfigureSubcommand.cs b/Jenny/Commands/ConfigureSubCommands/ControlRoomConfigureSubcommand.cs new file mode 100644 index 0000000..94294fb --- /dev/null +++ b/Jenny/Commands/ConfigureSubCommands/ControlRoomConfigureSubcommand.cs @@ -0,0 +1,18 @@ +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace Jenny.Commands.ConfigureSubCommands; + +public class ControlRoomConfigureSubCommand : ICommand<ConfigureCommand> { + public string Name { get; } = "controlroom"; + public string[]? Aliases { get; } + public string Description { get; } = "Configure the control room"; + public bool Unlisted { get; } + + public async Task Invoke(CommandContext ctx) { + if (ctx.Args.Length == 0) { + await ctx.Room.SendMessageEventAsync(new MessageBuilder("m.notice").WithBody("meow").Build()); + } + + } +} \ No newline at end of file diff --git a/Jenny/Commands/ImgCommand.cs b/Jenny/Commands/ImgCommand.cs new file mode 100644 index 0000000..9a4ed0c --- /dev/null +++ b/Jenny/Commands/ImgCommand.cs @@ -0,0 +1,134 @@ +using System.Diagnostics; +using System.Numerics; +using ArcaneLibs; +using ArcaneLibs.Extensions; +using LibMatrix.EventTypes.Spec; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace Jenny.Commands; + +public class ImgCommand : ICommand { + public string Name { get; } = "img"; + public string[]? Aliases { get; } = []; + public string Description { get; } + public bool Unlisted { get; } = true; + + public async Task Invoke(CommandContext ctx) { + int count = 1; + if (ctx.Args is { Length: 1 }) + int.TryParse(ctx.Args[0], out count); + + for (var i = 0; i < count; i++) { + new Thread(async () => { + var bigNoise = GenerateHeightMap(5000, 2000); + await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent("m.image", "src_noise.png") { + Url = await ctx.Homeserver.UploadFile("data.png", await Float2DArrayToPng(bigNoise), "image/png"), + FileInfo = new() { + Width = bigNoise.GetWidth(), + Height = bigNoise.GetHeight() + } + }); + }).Start(); + } + + } + + public async Task<byte[]> Float2DArrayToPng(float[,] data) { + //dump heightmap as PPM + Console.WriteLine($"{DateTime.Now} Converting to PNG"); + var width = data.GetLength(1); + var height = data.GetLength(0); + + //convert ppm to png with ffmpeg + var process = new Process { + StartInfo = new ProcessStartInfo { + // FileName = "/nix/store/4hz763c5w2hnzm55ll5vgfgmrr6i9kgg-imagemagick-7.1.1-28/bin/convert", + FileName = "convert", + Arguments = $"ppm:- png:-", + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true + } + }; + process.Start(); + await process.StandardInput.WriteLineAsync($"P2\n{width} {height}\n255"); + for (var i = 0; i < height; i++) { + for (var j = 0; j < width; j++) { + await process.StandardInput.WriteAsync($"{(int)(data[i, j] * 255)} "); + } + + // ppm.AppendLine(); + } + await process.StandardInput.FlushAsync(); + process.StandardInput.Close(); + await using var ms = new MemoryStream(); + await process.StandardOutput.BaseStream.CopyToAsync(ms); + ms.Position = 0; + Console.WriteLine($"{DateTime.Now} Converted to PNG"); + return ms.ToArray(); + } + + public float[,] GenerateHeightMap(int width, int height) { + var rnd = new Random(); + + var bigNoiseVector3 = new Vector3[height, width]; + for (var y = 0; y < bigNoiseVector3.GetLength(0); y++) { + for (var x = 0; x < bigNoiseVector3.GetLength(1); x++) { + bigNoiseVector3[y, x] = new Vector3(0, 0, 0); + } + } + + bigNoiseVector3[0, 0] = new Vector3(rnd.NextSingle(), rnd.NextSingle(), rnd.NextSingle()); + var last = bigNoiseVector3[0, 0]; + for (var y = 0; y < bigNoiseVector3.GetLength(0); y++) { + if (y > 0) break; + for (var x = 0; x < bigNoiseVector3.GetLength(1); x++) { + float currentX = x; + float currentY = y; + int steps = 0; + int maxSteps = 1000; + while (steps++ < maxSteps) { + if (currentX < 0) break; + if (currentY < 0) break; + if (currentX > bigNoiseVector3.GetWidth() - 1) break; + if (currentY > bigNoiseVector3.GetHeight() - 1) break; + + var current = bigNoiseVector3[(int)currentY, (int)currentX]; + // if (current is {X: 0f, Y: 0f, Z: 0f}) { + // bigNoiseVector3[currentY, currentX] = current = new Vector3(rnd.NextSingle(), rnd.NextSingle(), rnd.NextSingle()); + // } + + current = new(last.X, last.Y, last.Z); + var diff = new Vector3( + MathUtil.Map(rnd.NextSingle(), 0f, 1f, -0.2f, 0.2f), + MathUtil.Map(rnd.NextSingle(), 0f, 1f, -0.2f, 0.2f), + -0.1f + ); + current += diff; + bigNoiseVector3[(int)currentY, (int)currentX] = current; + + // Console.WriteLine("{0}/{1}={2} (+{3})", currentX, currentY, current, diff); + currentX += current.X; + currentY += current.Y; + + // if (current.X > 0.666f) currentX++; + // else if (current.X < 0.333f) currentX--; + // if (current.Y > 0.666f) currentY++; + // else if (current.Y < 0.333f) currentY--; + + last = current; + } + } + } + + var bigNoise = new float[height, width]; + for (var i = 0; i < bigNoise.GetLength(0); i++) { + for (var j = 0; j < bigNoise.GetLength(1); j++) { + // bigNoise[i, j] = (float) (bigNoiseVector[i, j].Length() / Math.Sqrt(2)); + bigNoise[i, j] = (float)(bigNoiseVector3[i, j].Z); + } + } + + return bigNoise; + } +} \ No newline at end of file diff --git a/Jenny/Commands/PatCommand.cs b/Jenny/Commands/PatCommand.cs new file mode 100644 index 0000000..efceaa4 --- /dev/null +++ b/Jenny/Commands/PatCommand.cs @@ -0,0 +1,164 @@ +using System.Text; +using LibMatrix.EventTypes.Spec.State; +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace Jenny.Commands; + +public class PatCommand : ICommand { + public string Name { get; } = "pat"; + public string[]? Aliases { get; } = [ "patpat", "patpatpat" ]; + public string Description { get; } + public bool Unlisted { get; } = true; + + public async Task Invoke(CommandContext ctx) { + int count = 1; + if (ctx.Args is { Length: 1 }) + int.TryParse(ctx.Args[0], out count); + + var selfName = + (await ctx.Room.GetStateAsync<RoomMemberEventContent>(RoomMemberEventContent.EventId, ctx.Homeserver.UserId))?.DisplayName + ?? (await ctx.Homeserver.GetProfileAsync(ctx.Homeserver.UserId)).DisplayName + ?? ctx.Homeserver.WhoAmI.UserId; + + var remoteName = + ctx.MessageEvent.Sender == null + ? null + : (await ctx.Room.GetStateAsync<RoomMemberEventContent>(RoomMemberEventContent.EventId, ctx.MessageEvent.Sender))?.DisplayName + ?? (await ctx.Homeserver.GetProfileAsync(ctx.MessageEvent.Sender)).DisplayName + ?? ctx.MessageEvent.Sender; + + var msb = new MessageBuilder("m.emote"); + var pat = new StringBuilder(); + var msg = $"snuggles {remoteName}"; + + Console.WriteLine(pat.ToString()); + // msb.WithHtmlTag("code", await GenerateSkyboxAroundString(msg, ctx)); + msb.WithBody(msg); + + await ctx.Room.SendMessageEventAsync(msb.Build()); + Console.WriteLine(msb.Build().FormattedBody); + + } + +#region old stuff + // TODO: implement: + // var selfName = + // (await ctx.Room.GetStateAsync<RoomMemberEventContent>(RoomMemberEventContent.EventId, ctx.Homeserver.UserId))?.DisplayName + // ?? (await ctx.Homeserver.GetProfileAsync(ctx.Homeserver.UserId)).DisplayName + // ?? ctx.Homeserver.WhoAmI.UserId; + // + // var remoteName = + // ctx.MessageEvent.Sender == null + // ? null + // : (await ctx.Room.GetStateAsync<RoomMemberEventContent>(RoomMemberEventContent.EventId, ctx.MessageEvent.Sender))?.DisplayName + // ?? (await ctx.Homeserver.GetProfileAsync(ctx.MessageEvent.Sender)).DisplayName + // ?? ctx.MessageEvent.Sender; + + // var msb = new MessageBuilder(); + // var pat = new StringBuilder(); + // var msg = $"{selfName} snuggles {remoteName}"; + + // Console.WriteLine(pat.ToString()); + // msb.WithHtmlTag("code", await GenerateSkyboxAroundString(msg, ctx)); + // Console.WriteLine(msb.Build().FormattedBody); +//} + + // + // + // private class CharacterWeight { + // public float Width { get; set; } + // public float Density { get; set; } + // } + // + // private Dictionary<char, CharacterWeight> starrySkyCharacters = new Dictionary<char, CharacterWeight> { + // { ' ', new CharacterWeight { Width = 0.5f, Density = 0.1f } }, // Space has the lowest density and width + // { '.', new CharacterWeight { Width = 0.2f, Density = 0.2f } }, // Dot has low density but small width + // { '+', new CharacterWeight { Width = 0.6f, Density = 0.3f } }, // Plus sign has medium density and width + // { '*', new CharacterWeight { Width = 0.7f, Density = 0.7f } }, // Asterisk has high density but medium width + // + // { '¨', new CharacterWeight { Width = 0.3f, Density = 0.2f } }, + // { '˜', new CharacterWeight { Width = 0.4f, Density = 0.3f } }, + // { 'ˆ', new CharacterWeight { Width = 0.5f, Density = 0.4f } }, + // { '”', new CharacterWeight { Width = 0.6f, Density = 0.5f } }, + // { '⍣', new CharacterWeight { Width = 0.8f, Density = 0.7f } }, + // { '~', new CharacterWeight { Width = 0.9f, Density = 0.8f } }, + // { '⊹', new CharacterWeight { Width = 1.2f, Density = 1.1f } }, + // { '٭', new CharacterWeight { Width = 1.3f, Density = 1.2f } }, + // { '„', new CharacterWeight { Width = 1.4f, Density = 1.3f } }, + // { '¸', new CharacterWeight { Width = 1.5f, Density = 1.4f } }, + // { '¤', new CharacterWeight { Width = 1.9f, Density = 1.8f } }, + // { '✬', new CharacterWeight { Width = 2.1f, Density = 2.0f } }, + // { '°', new CharacterWeight { Width = 0.6f, Density = 0.35f } }, + // { '•', new CharacterWeight { Width = 0.6f, Density = 0.4f } }, + // { '✡', new CharacterWeight { Width = 2.0f, Density = 4.0f } }, + // { '#', new CharacterWeight { Width = 1.0f, Density = 1.0f } }, + // }; + // + // private Dictionary<char, CharacterWeight> characterWeights = new Dictionary<char, CharacterWeight> { + // { 'a', new() { Density = 1, Width = 1 } } + // }; + // + // private async Task<string> GenerateSkyboxAroundString(string str, CommandContext ctx) { + // var sb = new StringBuilder(); + // int scale = 32; + // var outerTopBottomBorder = 4; + // var outerLeftRightBorder = 2; + // var innerTopBottomBorder = 1; + // var innerLeftRightBorder = 2; + // + // var innerBorder = 2; + // + // var width = str.Length + outerLeftRightBorder * 2 + innerLeftRightBorder * 2; + // var height = outerTopBottomBorder * 2 + innerTopBottomBorder * 2 + 1; + // var skybox = new char[height, width]; + // var bigNoise = GenerateHeightMap(2000, 1000); + // + // // await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent("m.image", "heightmap.png") { + // // Url = await Float2DArrayToMxc(noise, ctx), + // // FileInfo = new() { + // // Width = noise.GetLength(1), + // // Height = noise.GetLength(0) + // // } + // // }); + // // + // // //fill skybox with characters according to gradient noise + // // for (var i = 0; i < height; i++) { + // // for (var j = 0; j < width; j++) { + // // var c = ' '; + // // var shuffled = Random.Shared.GetItems(starrySkyCharacters.ToArray(), starrySkyCharacters.Count); + // // var cellWeight = noise[i, j]; + // // var item = starrySkyCharacters.OrderByDescending(x => x.Value.Density).FirstOrDefault(x => x.Value.Density <= cellWeight); + // // if (item.Value != null) { + // // c = item.Key; + // // } + // // + // // // foreach (var (key, value) in starrySkyCharacters) { + // // // var diff = Math.Abs(noise[i, j] - value.Density); + // // // if (diff < min) { + // // // min = diff; + // // // c = key; + // // // } + // // // } + // // + // // skybox[i, j] = c; + // // } + // // } + // // + // // for (var i = 0; i < str.Length; i++) { + // // skybox[outerTopBottomBorder + innerTopBottomBorder, i + outerLeftRightBorder + innerLeftRightBorder] = str[i]; + // // } + // // + // // for (var i = 0; i < height; i++) { + // // for (var j = 0; j < width; j++) { + // // sb.Append(skybox[i, j]); + // // } + // // + // // sb.AppendLine(); + // // } + // + // return sb.ToString(); + // } + +#endregion +} \ No newline at end of file diff --git a/Jenny/Handlers/CommandResultHandler.cs b/Jenny/Handlers/CommandResultHandler.cs new file mode 100644 index 0000000..767944a --- /dev/null +++ b/Jenny/Handlers/CommandResultHandler.cs @@ -0,0 +1,40 @@ +using ArcaneLibs; +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace Jenny.Handlers; + +public static class CommandResultHandler { + private static string binDir = FileUtils.GetBinDir(); + + public static async Task HandleAsync(CommandResult res) { + { + if (res.Success) return; + var room = res.Context.Room; + var hs = res.Context.Homeserver; + var msb = new MessageBuilder(); + if (res.Result == CommandResult.CommandResultType.Failure_Exception) { + var angryEmojiPath = Path.Combine(binDir, "Resources", "Stickers", "JennyAngryPink.webp"); + var hash = await FileUtils.GetFileSha384Async(angryEmojiPath); + var angryEmoji = await hs.NamedCaches.FileCache.GetOrSetValueAsync(hash, async () => { + await using var fs = File.OpenRead(angryEmojiPath); + return await hs.UploadFile("JennyAngryPink.webp", fs, "image/webp"); + }); + msb.WithCustomEmoji(angryEmoji, "JennyAngryPink") + .WithColoredBody("#EE4444", "An error occurred during the execution of this command") + .WithCodeBlock(res.Exception!.ToString(), "csharp"); + } + // else if(res.Result == CommandResult.CommandResultType.) { + // msb.AddMessage(new RoomMessageEventContent("m.notice", "An error occurred during the execution of this command")); + // } + // var msg = res.Result switch { + // CommandResult.CommandResultType.Failure_Exception => MessageFormatter.FormatException("An error occurred during the execution of this command", res.Exception!) + // CommandResult.CommandResultType.Failure_NoPermission => new RoomMessageEventContent("m.notice", "You do not have permission to run this command!"), + // CommandResult.CommandResultType.Failure_InvalidCommand => new RoomMessageEventContent("m.notice", $"Command \"{res.Context.CommandName}\" not found!"), + // _ => throw new ArgumentOutOfRangeException() + // }; + + await room.SendMessageEventAsync(msb.Build()); + } + } +} \ No newline at end of file diff --git a/Jenny/Handlers/InviteHandler.cs b/Jenny/Handlers/InviteHandler.cs new file mode 100644 index 0000000..128de44 --- /dev/null +++ b/Jenny/Handlers/InviteHandler.cs @@ -0,0 +1,12 @@ +using LibMatrix.EventTypes.Spec; +using LibMatrix.Utilities.Bot.Services; + +namespace Jenny.Handlers; + +public static class InviteHandler { + public static async Task HandleAsync(InviteHandlerHostedService.InviteEventArgs invite) { + var room = invite.Homeserver.GetRoom(invite.RoomId); + await room.JoinAsync(); + await room.SendMessageEventAsync(new RoomMessageEventContent("m.notice", "Hello! I'm Jenny!")); + } +} \ No newline at end of file diff --git a/Jenny/Jenny.csproj b/Jenny/Jenny.csproj new file mode 100644 index 0000000..c97a412 --- /dev/null +++ b/Jenny/Jenny.csproj @@ -0,0 +1,36 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>preview</LangVersion> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + <PublishAot>false</PublishAot> + <InvariantGlobalization>true</InvariantGlobalization> + <!-- <PublishTrimmed>true</PublishTrimmed>--> + <!-- <PublishReadyToRun>true</PublishReadyToRun>--> + <!-- <PublishSingleFile>true</PublishSingleFile>--> + <!-- <PublishReadyToRunShowWarnings>true</PublishReadyToRunShowWarnings>--> + <!-- <PublishTrimmedShowLinkerSizeComparison>true</PublishTrimmedShowLinkerSizeComparison>--> + <!-- <PublishTrimmedShowLinkerSizeComparisonWarnings>true</PublishTrimmedShowLinkerSizeComparisonWarnings>--> + </PropertyGroup> + + <ItemGroup> + <ProjectReference Include="..\LibMatrix\LibMatrix\LibMatrix.csproj" /> + <ProjectReference Include="..\LibMatrix\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj" /> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> + </ItemGroup> + <ItemGroup> + <Content Include="appsettings*.json"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Resources\**\*"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Remove="Resources\.git\**\*"/> + </ItemGroup> +</Project> diff --git a/Jenny/JennyBot.cs b/Jenny/JennyBot.cs new file mode 100644 index 0000000..2ba835d --- /dev/null +++ b/Jenny/JennyBot.cs @@ -0,0 +1,32 @@ +using LibMatrix.Homeservers; +using LibMatrix.RoomTypes; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Jenny; + +public class JennyBot(AuthenticatedHomeserverGeneric hs, ILogger<JennyBot> logger, JennyConfiguration configuration) : IHostedService { + private Task _listenerTask; + + // private GenericRoom _policyRoom; + private GenericRoom? _logRoom; + private GenericRoom? _controlRoom; + + /// <summary>Triggered when the application host is ready to start the service.</summary> + /// <param name="cancellationToken">Indicates that the start process has been aborted.</param> + public async Task StartAsync(CancellationToken cancellationToken) { + _listenerTask = Run(cancellationToken); + logger.LogInformation("Bot started!"); + } + + private async Task Run(CancellationToken cancellationToken) { + + } + + /// <summary>Triggered when the application host is performing a graceful shutdown.</summary> + /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param> + public async Task StopAsync(CancellationToken cancellationToken) { + logger.LogInformation("Shutting down bot!"); + } + +} diff --git a/Jenny/JennyConfiguration.cs b/Jenny/JennyConfiguration.cs new file mode 100644 index 0000000..a1609e7 --- /dev/null +++ b/Jenny/JennyConfiguration.cs @@ -0,0 +1,9 @@ +using Microsoft.Extensions.Configuration; + +namespace Jenny; + +public class JennyConfiguration { + public JennyConfiguration(IConfiguration config) => config.GetRequiredSection("Jenny").Bind(this); + + public List<string> Admins { get; set; } = new(); +} diff --git a/Jenny/Program.cs b/Jenny/Program.cs new file mode 100644 index 0000000..2ee2c9b --- /dev/null +++ b/Jenny/Program.cs @@ -0,0 +1,33 @@ +using Jenny; +using Jenny.Handlers; +using LibMatrix.Services; +using LibMatrix.Utilities.Bot; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +var builder = Host.CreateDefaultBuilder(args); + +builder.ConfigureHostOptions(host => { + host.ServicesStartConcurrently = true; + host.ServicesStopConcurrently = true; + host.ShutdownTimeout = TimeSpan.FromSeconds(5); +}); + +if (Environment.GetEnvironmentVariable("JENNY_APPSETTINGS_PATH") is string path) + builder.ConfigureAppConfiguration(x => x.AddJsonFile(path)); + +var host = builder.ConfigureServices((_, services) => { + services.AddSingleton<JennyConfiguration>(); + + services.AddRoryLibMatrixServices(new() { + AppName = "Jenny" + }); + services.AddMatrixBot().AddCommandHandler().DiscoverAllCommands() + .WithInviteHandler(InviteHandler.HandleAsync) + .WithCommandResultHandler(CommandResultHandler.HandleAsync); + + services.AddHostedService<JennyBot>(); +}).UseConsoleLifetime().Build(); + +await host.RunAsync(); \ No newline at end of file diff --git a/Jenny/Properties/launchSettings.json b/Jenny/Properties/launchSettings.json new file mode 100644 index 0000000..997e294 --- /dev/null +++ b/Jenny/Properties/launchSettings.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "Default": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + + } + }, + "Development": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + }, + "Local config": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Local" + } + } + } +} diff --git a/Jenny/Resources b/Jenny/Resources new file mode 160000 +Subproject 46edc2287e1cc9009a9a72447a6603e959a8971 diff --git a/Jenny/appsettings.Development.json b/Jenny/appsettings.Development.json new file mode 100644 index 0000000..224d0da --- /dev/null +++ b/Jenny/appsettings.Development.json @@ -0,0 +1,24 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "LibMatrixBot": { + // The homeserver to connect to + "Homeserver": "rory.gay", + // The access token to use + "AccessToken": "syt_xxxxxxxxxxxxxxxxx", + // The command prefix + "Prefix": "?" + }, + "ModerationBot": { + // List of people who should be invited to the control room + "Admins": [ + "@emma:conduit.rory.gay", + "@emma:rory.gay" + ] + } +} diff --git a/Jenny/appsettings.json b/Jenny/appsettings.json new file mode 100644 index 0000000..6ba02f3 --- /dev/null +++ b/Jenny/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} |