fixed most compiler complaints in discord interface
Some checks failed
gitea.arg.rip/vassago/pipeline/head There was a failure building this commit

This commit is contained in:
adam 2025-02-25 23:45:30 -05:00
parent 736e3cb763
commit 3ed37959ad
8 changed files with 64 additions and 88 deletions

View File

@ -4,6 +4,7 @@ namespace vassago
using vassago; using vassago;
using vassago.Models; using vassago.Models;
using vassago.TwitchInterface; using vassago.TwitchInterface;
using vassago.ProtocolInterfaces.DiscordInterface;
internal class ConsoleService : IHostedService internal class ConsoleService : IHostedService
{ {
@ -27,7 +28,7 @@ namespace vassago
if (DiscordTokens?.Any() ?? false) if (DiscordTokens?.Any() ?? false)
foreach (var dt in DiscordTokens) foreach (var dt in DiscordTokens)
{ {
var d = new DiscordInterface.DiscordInterface(); var d = new DiscordInterface();
await d.Init(dt); await d.Init(dt);
ProtocolInterfaces.ProtocolList.discords.Add(d); ProtocolInterfaces.ProtocolList.discords.Add(d);
} }

View File

@ -13,14 +13,14 @@ using Microsoft.EntityFrameworkCore;
using System.Threading; using System.Threading;
using System.Reactive.Linq; using System.Reactive.Linq;
namespace vassago.DiscordInterface; namespace vassago.ProtocolInterfaces.DiscordInterface;
public class DiscordInterface public class DiscordInterface
{ {
internal const string PROTOCOL = "discord"; internal const string PROTOCOL = "discord";
internal DiscordSocketClient client; internal DiscordSocketClient client;
private bool eventsSignedUp = false; private bool eventsSignedUp = false;
private static SemaphoreSlim discordChannelSetup = new SemaphoreSlim(1, 1); private static readonly SemaphoreSlim discordChannelSetup = new(1, 1);
private Channel protocolAsChannel; private Channel protocolAsChannel;
public async Task Init(string token) public async Task Init(string token)
@ -33,8 +33,8 @@ public class DiscordInterface
Console.WriteLine(msg.ToString()); Console.WriteLine(msg.ToString());
return Task.CompletedTask; return Task.CompletedTask;
}; };
client.Connected += SelfConnected; client.Connected += () => Task.Run(SelfConnected);
client.Ready += ClientReady; client.Ready += () => Task.Run(ClientReady);
await client.LoginAsync(TokenType.Bot, token); await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync(); await client.StartAsync();
@ -60,7 +60,7 @@ public class DiscordInterface
ReactionsPossible = true, ReactionsPossible = true,
ExternalId = null, ExternalId = null,
Protocol = PROTOCOL, Protocol = PROTOCOL,
SubChannels = new List<Channel>() SubChannels = []
}; };
} }
else else
@ -87,7 +87,7 @@ public class DiscordInterface
client.MessageReceived += MessageReceived; client.MessageReceived += MessageReceived;
// _client.MessageUpdated += // _client.MessageUpdated +=
//client.UserJoined += UserJoined; client.UserJoined += UserJoined;
client.SlashCommandExecuted += SlashCommandHandler; client.SlashCommandExecuted += SlashCommandHandler;
//client.ChannelCreated += //client.ChannelCreated +=
// _client.ChannelDestroyed += // _client.ChannelDestroyed +=
@ -110,7 +110,7 @@ public class DiscordInterface
} }
} }
private async Task SelfConnected() private void SelfConnected()
{ {
var selfAccount = UpsertAccount(client.CurrentUser, protocolAsChannel); var selfAccount = UpsertAccount(client.CurrentUser, protocolAsChannel);
selfAccount.DisplayName = client.CurrentUser.Username; selfAccount.DisplayName = client.CurrentUser.Username;
@ -119,12 +119,13 @@ public class DiscordInterface
private async Task MessageReceived(SocketMessage messageParam) private async Task MessageReceived(SocketMessage messageParam)
{ {
var suMessage = messageParam as SocketUserMessage; if(messageParam is not SocketUserMessage)
if (suMessage == null)
{ {
Console.WriteLine($"{messageParam.Content}, but not a user message"); Console.WriteLine($"{messageParam.Content}, but not a user message");
return; return;
} }
var suMessage = messageParam as SocketUserMessage;
Console.WriteLine($"#{suMessage.Channel}[{DateTime.Now}][{suMessage.Author.Username} [id={suMessage.Author.Id}]][msg id: {suMessage.Id}] {suMessage.Content}"); Console.WriteLine($"#{suMessage.Channel}[{DateTime.Now}][{suMessage.Author.Username} [id={suMessage.Author.Id}]][msg id: {suMessage.Id}] {suMessage.Content}");
var m = UpsertMessage(suMessage); var m = UpsertMessage(suMessage);
@ -138,22 +139,14 @@ public class DiscordInterface
m.ActedOn = true; // for its own ruposess it might act on it later, but either way, fuck it, we checked. m.ActedOn = true; // for its own ruposess it might act on it later, but either way, fuck it, we checked.
} }
private void UserJoined(SocketGuildUser arg) private Task UserJoined(SocketGuildUser arg)
{ {
var guild = UpsertChannel(arg.Guild); var guild = UpsertChannel(arg.Guild);
var defaultChannel = UpsertChannel(arg.Guild.DefaultChannel); var defaultChannel = UpsertChannel(arg.Guild.DefaultChannel);
defaultChannel.ParentChannel = guild; defaultChannel.ParentChannel = guild;
var u = UpsertAccount(arg, guild); var u = UpsertAccount(arg, guild);
u.DisplayName = arg.DisplayName; u.DisplayName = arg.DisplayName;
} return null;
private async Task ButtonHandler(SocketMessageComponent component)
{
switch (component.Data.CustomId)
{
case "custom-id":
await component.RespondAsync($"{component.User.Mention}, it's been here the whole time!");
break;
}
} }
internal static async Task SlashCommandHandler(SocketSlashCommand command) internal static async Task SlashCommandHandler(SocketSlashCommand command)
{ {
@ -181,13 +174,11 @@ public class DiscordInterface
break; break;
} }
} }
internal vassago.Models.Attachment UpsertAttachment(IAttachment dAttachment) internal static vassago.Models.Attachment UpsertAttachment(IAttachment dAttachment)
{ {
var a = Rememberer.SearchAttachment(ai => ai.ExternalId == dAttachment.Id); var a = Rememberer.SearchAttachment(ai => ai.ExternalId == dAttachment.Id)
if (a == null) ?? new vassago.Models.Attachment();
{
a = new vassago.Models.Attachment();
}
a.ContentType = dAttachment.ContentType; a.ContentType = dAttachment.ContentType;
a.Description = dAttachment.Description; a.Description = dAttachment.Description;
a.Filename = dAttachment.Filename; a.Filename = dAttachment.Filename;
@ -198,16 +189,16 @@ public class DiscordInterface
} }
internal Message UpsertMessage(IUserMessage dMessage) internal Message UpsertMessage(IUserMessage dMessage)
{ {
var m = Rememberer.SearchMessage(mi => mi.ExternalId == dMessage.Id.ToString() && mi.Protocol == PROTOCOL); var m = Rememberer.SearchMessage(mi => mi.ExternalId == dMessage.Id.ToString() && mi.Protocol == PROTOCOL)
if (m == null) ?? new()
{
Protocol = PROTOCOL
};
if (dMessage.Attachments?.Count > 0)
{ {
m = new Message(); m.Attachments = [];
m.Protocol = PROTOCOL;
}
m.Attachments = m.Attachments ?? new List<vassago.Models.Attachment>();
if (dMessage.Attachments?.Any() == true)
{
m.Attachments = new List<vassago.Models.Attachment>();
foreach (var da in dMessage.Attachments) foreach (var da in dMessage.Attachments)
{ {
m.Attachments.Add(UpsertAttachment(da)); m.Attachments.Add(UpsertAttachment(da));
@ -226,7 +217,7 @@ public class DiscordInterface
&& (dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) > 0)); && (dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) > 0));
m.Reply = (t) => { return dMessage.ReplyAsync(t); }; m.Reply = (t) => { return dMessage.ReplyAsync(t); };
m.React = (e) => { return attemptReact(dMessage, e); }; m.React = (e) => { return AttemptReact(dMessage, e); };
Rememberer.RememberChannel(m.Channel); Rememberer.RememberChannel(m.Channel);
return m; return m;
} }
@ -242,7 +233,7 @@ public class DiscordInterface
c.DisplayName = channel.Name; c.DisplayName = channel.Name;
c.ExternalId = channel.Id.ToString(); c.ExternalId = channel.Id.ToString();
c.ChannelType = (channel is IPrivateChannel) ? vassago.Models.Enumerations.ChannelType.DM : vassago.Models.Enumerations.ChannelType.Normal; c.ChannelType = (channel is IPrivateChannel) ? vassago.Models.Enumerations.ChannelType.DM : vassago.Models.Enumerations.ChannelType.Normal;
c.Messages = c.Messages ?? new List<Message>(); c.Messages ??= [];
c.Protocol = PROTOCOL; c.Protocol = PROTOCOL;
if (channel is IGuildChannel) if (channel is IGuildChannel)
{ {
@ -270,7 +261,6 @@ public class DiscordInterface
if (channel is IGuildChannel) if (channel is IGuildChannel)
{ {
parentChannel = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == PROTOCOL); parentChannel = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == PROTOCOL);
} }
else if (channel is IPrivateChannel) else if (channel is IPrivateChannel)
{ {
@ -281,8 +271,7 @@ public class DiscordInterface
parentChannel = protocolAsChannel; parentChannel = protocolAsChannel;
Console.Error.WriteLine($"trying to upsert channel {channel.Id}/{channel.Name}, but it's neither guildchannel nor private channel. shrug.jpg"); Console.Error.WriteLine($"trying to upsert channel {channel.Id}/{channel.Name}, but it's neither guildchannel nor private channel. shrug.jpg");
} }
if (parentChannel.SubChannels == null) parentChannel.SubChannels ??= [];
parentChannel.SubChannels = new List<Channel>();
parentChannel.SubChannels.Add(c); parentChannel.SubChannels.Add(c);
Rememberer.RememberChannel(parentChannel); Rememberer.RememberChannel(parentChannel);
@ -302,10 +291,10 @@ public class DiscordInterface
c.DisplayName = channel.Name; c.DisplayName = channel.Name;
c.ExternalId = channel.Id.ToString(); c.ExternalId = channel.Id.ToString();
c.ChannelType = vassago.Models.Enumerations.ChannelType.OU; c.ChannelType = vassago.Models.Enumerations.ChannelType.OU;
c.Messages = c.Messages ?? new List<Message>(); c.Messages ??= [];
c.Protocol = protocolAsChannel.Protocol; c.Protocol = protocolAsChannel.Protocol;
c.ParentChannel = protocolAsChannel; c.ParentChannel = protocolAsChannel;
c.SubChannels = c.SubChannels ?? new List<Channel>(); c.SubChannels ??= [];
c.MaxAttachmentBytes = channel.MaxUploadLimit; c.MaxAttachmentBytes = channel.MaxUploadLimit;
c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); }; c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); };
@ -313,13 +302,11 @@ public class DiscordInterface
Rememberer.RememberChannel(c); Rememberer.RememberChannel(c);
return c; return c;
} }
internal Account UpsertAccount(IUser user, Channel inChannel) internal static Account UpsertAccount(IUser user, Channel inChannel)
{ {
var acc = Rememberer.SearchAccount(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id); var acc = Rememberer.SearchAccount(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel.Id);
if (acc == null) acc ??= new Account();
{
acc = new Account();
}
acc.Username = user.Username; acc.Username = user.Username;
acc.ExternalId = user.Id.ToString(); acc.ExternalId = user.Id.ToString();
acc.IsBot = user.IsBot || user.IsWebhook; acc.IsBot = user.IsBot || user.IsWebhook;
@ -328,15 +315,14 @@ public class DiscordInterface
acc.IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol)); acc.IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
//db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol)); //db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
if (acc.IsUser == null)
{ acc.IsUser ??= new User() { Accounts = [ acc ] };
acc.IsUser = new User() { Accounts = new List<Account>() { acc } };
}
Rememberer.RememberAccount(acc); Rememberer.RememberAccount(acc);
return acc; return acc;
} }
private Task attemptReact(IUserMessage msg, string e) private static Task AttemptReact(IUserMessage msg, string e)
{ {
var c = Rememberer.SearchChannel(c => c.ExternalId == msg.Channel.Id.ToString());// db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id.ToString()); var c = Rememberer.SearchChannel(c => c.ExternalId == msg.Channel.Id.ToString());// db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id.ToString());
//var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides //var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides

View File

@ -7,7 +7,7 @@ using Discord.WebSocket;
using Discord; using Discord;
using Discord.Net; using Discord.Net;
namespace vassago.DiscordInterface namespace vassago.ProtocolInterfaces.DiscordInterface
{ {
public static class SlashCommandsHelper public static class SlashCommandsHelper
{ {

View File

@ -4,35 +4,29 @@ using System.Text;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using vassago.Models; using vassago.Models;
using vassago.WebInterface.Models;
namespace vassago.Controllers; namespace vassago.WebInterface.Controllers;
public class ChannelsController : Controller public class ChannelsController(ChattingContext db) : Controller
{ {
private readonly ILogger<ChannelsController> _logger; private ChattingContext Database => db;
private readonly ChattingContext _db;
public ChannelsController(ILogger<ChannelsController> logger, ChattingContext db) public IActionResult Index()
{ {
_logger = logger; return Database.Channels != null ?
_db = db; View(Database.Channels.Include(u => u.ParentChannel).ToList().OrderBy(c => c.LineageSummary)) :
}
public async Task<IActionResult> Index(string searchString)
{
return _db.Channels != null ?
View(_db.Channels.Include(u => u.ParentChannel).ToList().OrderBy(c => c.LineageSummary)) :
Problem("Entity set '_db.Channels' is null."); Problem("Entity set '_db.Channels' is null.");
} }
public async Task<IActionResult> Details(Guid id) public async Task<IActionResult> Details(Guid id)
{ {
if(_db.Channels == null) if(Database.Channels == null)
return Problem("Entity set '_db.Channels' is null."); return Problem("Entity set '_db.Channels' is null.");
//"but adam", says the strawman, "why load *every* channel and walk your way up? surely there's a .Load command that works or something." //"but adam", says the strawman, "why load *every* channel and walk your way up? surely there's a .Load command that works or something."
//eh. I checked. Not really. You could make an SQL view that recurses its way up, meh idk how. You could just eagerly load *every* related object... //eh. I checked. Not really. You could make an SQL view that recurses its way up, meh idk how. You could just eagerly load *every* related object...
//but that would take in all the messages. //but that would take in all the messages.
//realistically I expect this will have less than 1MB of total "channels", and several GB of total messages per (text) channel. //realistically I expect this will have less than 1MB of total "channels", and several GB of total messages per (text) channel.
var AllChannels = await _db.Channels var AllChannels = await Database.Channels
.Include(u => u.SubChannels) .Include(u => u.SubChannels)
.Include(u => u.Users) .Include(u => u.Users)
.Include(u => u.ParentChannel) .Include(u => u.ParentChannel)
@ -46,7 +40,7 @@ public class ChannelsController : Controller
walker = walker.ParentChannel; walker = walker.ParentChannel;
} }
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append("["); sb.Append('[');
sb.Append($"{{text: \"{channel.SubChannels?.Count}\", nodes: ["); sb.Append($"{{text: \"{channel.SubChannels?.Count}\", nodes: [");
var first=true; var first=true;
foreach(var subChannel in channel.SubChannels) foreach(var subChannel in channel.SubChannels)

View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments; using Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments;
using vassago.Models; using vassago.Models;
using vassago.WebInterface.Models;
namespace vassago.Controllers; namespace vassago.Controllers;

View File

@ -2,37 +2,31 @@ using System.Diagnostics;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using vassago.Models; using vassago.Models;
using vassago.WebInterface.Models;
namespace vassago.Controllers; namespace vassago.WebInterface.Controllers;
public class UsersController : Controller public class UsersController(ChattingContext db) : Controller
{ {
private readonly ILogger<UsersController> _logger; private ChattingContext Database => db;
private readonly ChattingContext _db;
public UsersController(ILogger<UsersController> logger, ChattingContext db) public async Task<IActionResult> Index()
{ {
_logger = logger; return Database.Users != null ?
_db = db; View(await Database.Users.Include(u => u.Accounts).ToListAsync()) :
}
public async Task<IActionResult> Index(string searchString)
{
return _db.Users != null ?
View(await _db.Users.Include(u => u.Accounts).ToListAsync()) :
Problem("Entity set '_db.Users' is null."); Problem("Entity set '_db.Users' is null.");
} }
public async Task<IActionResult> Details(Guid id) public async Task<IActionResult> Details(Guid id)
{ {
var user = await _db.Users var user = await Database.Users
.Include(u => u.Accounts) .Include(u => u.Accounts)
.FirstAsync(u => u.Id == id); .FirstAsync(u => u.Id == id);
var allTheChannels = await _db.Channels.ToListAsync(); var allTheChannels = await Database.Channels.ToListAsync();
foreach(var acc in user.Accounts) foreach(var acc in user.Accounts)
{ {
acc.SeenInChannel = allTheChannels.FirstOrDefault(c => c.Id == acc.SeenInChannel.Id); acc.SeenInChannel = allTheChannels.FirstOrDefault(c => c.Id == acc.SeenInChannel.Id);
} }
return _db.Users != null ? return Database.Users != null ?
View(user) : View(user) :
Problem("Entity set '_db.Users' is null."); Problem("Entity set '_db.Users' is null.");
} }

View File

@ -1,8 +1,8 @@
namespace vassago.Models; namespace vassago.WebInterface.Models;
public class ErrorPageViewModel public class ErrorPageViewModel
{ {
public string? RequestId { get; set; } public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
} }

View File

@ -1,4 +1,4 @@
@model ErrorPageViewModel @model vassago.WebInterface.Models.ErrorPageViewModel
@{ @{
ViewData["Title"] = "Error"; ViewData["Title"] = "Error";
} }