Compare commits

..

2 Commits

Author SHA1 Message Date
115035eb91 test/fix features 2023-06-20 21:38:25 -04:00
147cba7cd3 keep track of self 2023-06-20 21:26:44 -04:00
21 changed files with 95 additions and 43 deletions

View File

@ -10,17 +10,22 @@ using System.Collections.Generic;
public class Behaver public class Behaver
{ {
private static List<Behavior> behaviors { get; set; } = new List<Behavior>(); private ChattingContext _db;
public List<Account> Selves { get; internal set; } = new List<Account>();
public static List<Behavior> Behaviors { get; private set; } = new List<Behavior>();
internal Behaver() internal Behaver()
{ {
_db = new ChattingContext();
var subtypes = AppDomain.CurrentDomain.GetAssemblies() var subtypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(domainAssembly => domainAssembly.GetTypes()) .SelectMany(domainAssembly => domainAssembly.GetTypes())
.Where(type => type.IsSubclassOf(typeof(Behavior)) && !type.IsAbstract) .Where(type => type.IsSubclassOf(typeof(Behavior)) && !type.IsAbstract &&
type.GetCustomAttributes(typeof(StaticPlzAttribute),false)?.Any() == true)
.ToList(); .ToList();
foreach (var subtype in subtypes) foreach (var subtype in subtypes)
{ {
behaviors.Add((Behavior)Activator.CreateInstance(subtype)); Behaviors.Add((Behavior)Activator.CreateInstance(subtype));
} }
} }
static Behaver() { } static Behaver() { }
@ -34,7 +39,7 @@ public class Behaver
public async Task<bool> ActOn(Message message) public async Task<bool> ActOn(Message message)
{ {
foreach (var behavior in behaviors) foreach (var behavior in Behaviors)
{ {
if (behavior.ShouldAct(message)) if (behavior.ShouldAct(message))
{ {
@ -42,7 +47,7 @@ public class Behaver
message.ActedOn = true; message.ActedOn = true;
} }
} }
if (message.ActedOn == false && message.MentionsMe && message.Content.Contains('?')) if (message.ActedOn == false && message.MentionsMe && message.Content.Contains('?') && !Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
{ {
Console.WriteLine("providing bullshit nonanswer / admitting uselessness"); Console.WriteLine("providing bullshit nonanswer / admitting uselessness");
var responses = new List<string>(){ var responses = new List<string>(){
@ -54,7 +59,7 @@ public class Behaver
} }
if (message.ActedOn) if (message.ActedOn)
{ {
Shared.dbContext.SaveChanges(); _db.SaveChanges();
} }
return message.ActedOn; return message.ActedOn;
} }

View File

@ -8,13 +8,14 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
//expect a behavior to be created per mesage
public abstract class Behavior public abstract class Behavior
{ {
public abstract Task<bool> ActOn(Message message); public abstract Task<bool> ActOn(Message message);
public virtual bool ShouldAct(Message message) public virtual bool ShouldAct(Message message)
{ {
if(Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
return false;
return Regex.IsMatch(message.Content, $"{Trigger}\\b", RegexOptions.IgnoreCase); return Regex.IsMatch(message.Content, $"{Trigger}\\b", RegexOptions.IgnoreCase);
} }
@ -22,3 +23,6 @@ public abstract class Behavior
public abstract string Trigger { get; } public abstract string Trigger { get; }
public virtual string Description => Name; public virtual string Description => Name;
} }
public class StaticPlzAttribute : Attribute {}

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class ChatGPTSnark : Behavior public class ChatGPTSnark : Behavior
{ {
public override string Name => "ChatGPTSnark"; public override string Name => "ChatGPTSnark";

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class DefinitionSnarkCogDiss : Behavior public class DefinitionSnarkCogDiss : Behavior
{ {
public override string Name => "Definition Snarkiness: cognitivie dissonance"; public override string Name => "Definition Snarkiness: cognitivie dissonance";

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class DefinitionSnarkGaslight : Behavior public class DefinitionSnarkGaslight : Behavior
{ {
public override string Name => "Definition Snarkiness: gaslighting"; public override string Name => "Definition Snarkiness: gaslighting";

View File

@ -6,6 +6,8 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class Detiktokify : Behavior public class Detiktokify : Behavior
{ {
public override string Name { get => "Detiktokify"; } public override string Name { get => "Detiktokify"; }
@ -79,6 +81,7 @@ public class Detiktokify : Behavior
} }
else else
{ {
message.ActedOn = true;
Console.WriteLine($"file appears too big ({bytesize} bytes ({bytesize / (1024 * 1024)}MB)), not posting"); Console.WriteLine($"file appears too big ({bytesize} bytes ({bytesize / (1024 * 1024)}MB)), not posting");
} }
File.Delete(path); File.Delete(path);

View File

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class FiximageHeic : Behavior public class FiximageHeic : Behavior
{ {
public override string Name => "deheic"; public override string Name => "deheic";
@ -20,6 +21,8 @@ public class FiximageHeic : Behavior
private List<Attachment> heics = new List<Attachment>(); private List<Attachment> heics = new List<Attachment>();
public override bool ShouldAct(Message message) public override bool ShouldAct(Message message)
{ {
if(Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
return false;
if (message.Attachments?.Count() > 0) if (message.Attachments?.Count() > 0)
{ {
foreach (var att in message.Attachments) foreach (var att in message.Attachments)

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class GeneralSnarkCloudNative : Behavior public class GeneralSnarkCloudNative : Behavior
{ {
public override string Name => "general snarkiness: cloud native"; public override string Name => "general snarkiness: cloud native";
@ -17,6 +18,8 @@ public class GeneralSnarkCloudNative : Behavior
public override string Trigger => "certain tech buzzwords that no human uses in normal conversation"; public override string Trigger => "certain tech buzzwords that no human uses in normal conversation";
public override bool ShouldAct(Message message) public override bool ShouldAct(Message message)
{ {
if(Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
return false;
return Regex.IsMatch(message.Content, "\\bcloud( |-)?native\\b", RegexOptions.IgnoreCase) || return Regex.IsMatch(message.Content, "\\bcloud( |-)?native\\b", RegexOptions.IgnoreCase) ||
Regex.IsMatch(message.Content, "\\benterprise( |-)?(level|solution)\\b", RegexOptions.IgnoreCase); Regex.IsMatch(message.Content, "\\benterprise( |-)?(level|solution)\\b", RegexOptions.IgnoreCase);
} }

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class GeneralSnarkPlaying : Behavior public class GeneralSnarkPlaying : Behavior
{ {
public override string Name => "playin Snarkiness"; public override string Name => "playin Snarkiness";
@ -19,6 +20,8 @@ public class GeneralSnarkPlaying : Behavior
public override bool ShouldAct(Message message) public override bool ShouldAct(Message message)
{ {
if(Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
return false;
return Regex.IsMatch(message.Content, "^(s?he|(yo)?u|y'?all|they) thinks? i'?m (playin|jokin|kiddin)g?$", RegexOptions.IgnoreCase); return Regex.IsMatch(message.Content, "^(s?he|(yo)?u|y'?all|they) thinks? i'?m (playin|jokin|kiddin)g?$", RegexOptions.IgnoreCase);
} }
public override async Task<bool> ActOn(Message message) public override async Task<bool> ActOn(Message message)

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class GeneralSnarkSkynet : Behavior public class GeneralSnarkSkynet : Behavior
{ {
public override string Name => "Skynet Snarkiness"; public override string Name => "Skynet Snarkiness";

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class Gratitude : Behavior public class Gratitude : Behavior
{ {
public override string Name => "Gratitude"; public override string Name => "Gratitude";
@ -17,6 +18,8 @@ public class Gratitude : Behavior
public override bool ShouldAct(Message message) public override bool ShouldAct(Message message)
{ {
if(Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id))
return false;
return Regex.IsMatch(message.Content, "\\bthank (yo)?u\\b", RegexOptions.IgnoreCase) && message.MentionsMe; return Regex.IsMatch(message.Content, "\\bthank (yo)?u\\b", RegexOptions.IgnoreCase) && message.MentionsMe;
} }
public override async Task<bool> ActOn(Message message) public override async Task<bool> ActOn(Message message)
@ -28,7 +31,7 @@ public class Gratitude : Behavior
await message.Channel.SendMessage("you're welcome, citizen!"); await message.Channel.SendMessage("you're welcome, citizen!");
break; break;
case 1: case 1:
await message.React(""); await message.React(":)");
break; break;
case 2: case 2:
await message.React("\U0001F607"); //smiling face with halo await message.React("\U0001F607"); //smiling face with halo
@ -37,7 +40,7 @@ public class Gratitude : Behavior
switch (Shared.r.Next(9)) switch (Shared.r.Next(9))
{ {
case 0: case 0:
await message.React(""); //normal heart, usually rendered red await message.React("<3"); //normal heart, usually rendered red
break; break;
case 1: case 1:
await message.React("\U0001F9E1"); //orange heart await message.React("\U0001F9E1"); //orange heart

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class Joke : Behavior public class Joke : Behavior
{ {
public override string Name => "Joke"; public override string Name => "Joke";
@ -34,12 +35,12 @@ public class Joke : Behavior
{ {
var firstIndexAfterQuestionMark = thisJoke.LastIndexOf('?') + 1; var firstIndexAfterQuestionMark = thisJoke.LastIndexOf('?') + 1;
var straightline = thisJoke.Substring(0, firstIndexAfterQuestionMark); var straightline = thisJoke.Substring(0, firstIndexAfterQuestionMark);
var punchline = thisJoke.Substring(firstIndexAfterQuestionMark, thisJoke.Length - firstIndexAfterQuestionMark); var punchline = thisJoke.Substring(firstIndexAfterQuestionMark, thisJoke.Length - firstIndexAfterQuestionMark).Trim();
Task.WaitAll(message.Channel.SendMessage(straightline)); Task.WaitAll(message.Channel.SendMessage(straightline));
Thread.Sleep(TimeSpan.FromSeconds(Shared.r.Next(5, 30))); Thread.Sleep(TimeSpan.FromSeconds(Shared.r.Next(5, 30)));
//if (Shared.r.Next(8) == 0) //if (Shared.r.Next(8) == 0)
{ {
LaughAtOwnJoke.punchlinesAwaitingReaction.Add(punchline); Behaver.Behaviors.Add(new LaughAtOwnJoke(punchline));
} }
await message.Channel.SendMessage(punchline); await message.Channel.SendMessage(punchline);
// var myOwnMsg = await message.Channel.SendMessage(punchline); // var myOwnMsg = await message.Channel.SendMessage(punchline);

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
public class LaughAtOwnJoke : Behavior public class LaughAtOwnJoke : Behavior
{ {
public override string Name => "Laugh at own jokes"; public override string Name => "Laugh at own jokes";
@ -16,20 +17,23 @@ public class LaughAtOwnJoke : Behavior
public override string Trigger => "1 in 8"; public override string Trigger => "1 in 8";
public override string Description => Name; public override string Description => Name;
public static List<string> punchlinesAwaitingReaction = new List<string>(); private string _punchline{get;set;}
public LaughAtOwnJoke(string punchline)
{
_punchline = punchline;
}
public override bool ShouldAct(Message message) public override bool ShouldAct(Message message)
{ {
Console.WriteLine($"{message.Content} == {_punchline}");
//TODO: i need to keep track of myself from here somehow return message.Content == _punchline
//return false; && Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id);
return /*message.Author == me &&*/ punchlinesAwaitingReaction.Contains(message.Content);
} }
public override async Task<bool> ActOn(Message message) public override async Task<bool> ActOn(Message message)
{ {
punchlinesAwaitingReaction.Remove(message.Content);
await message.React("\U0001F60E"); //smiling face with sunglasses await message.React("\U0001F60E"); //smiling face with sunglasses
Behaver.Behaviors.Remove(this);
return true; return true;
} }
} }

View File

@ -10,6 +10,7 @@ using Newtonsoft.Json;
using vassago.Models; using vassago.Models;
using QRCoder; using QRCoder;
[StaticPlz]
public class PepTalk : Behavior public class PepTalk : Behavior
{ {
public override string Name => "PepTalk"; public override string Name => "PepTalk";

View File

@ -8,11 +8,12 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class PulseCheck : Behavior public class PulseCheck : Behavior
{ {
public override string Name => "pulse check"; public override string Name => "pulse check";
public override string Trigger => "!pluse ?check"; public override string Trigger => "!pulse ?check";
public override async Task<bool> ActOn(Message message) public override async Task<bool> ActOn(Message message)
{ {

View File

@ -10,6 +10,7 @@ using Newtonsoft.Json;
using vassago.Models; using vassago.Models;
using QRCoder; using QRCoder;
[StaticPlz]
public class QRify : Behavior public class QRify : Behavior
{ {
public override string Name => "qr-ify"; public override string Name => "qr-ify";

View File

@ -3,6 +3,8 @@ namespace vassago.Behavior;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class UnitConvert : Behavior public class UnitConvert : Behavior
{ {
public override string Name => "Unit conversion"; public override string Name => "Unit conversion";
@ -21,11 +23,12 @@ public class UnitConvert : Behavior
if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric)) if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric))
{ {
await message.Channel.SendMessage(Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower())); await message.Channel.SendMessage(Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower()));
return true;
} }
await message.Channel.SendMessage("mysteriously semi-parsable"); await message.Channel.SendMessage("mysteriously semi-parsable");
return true;
} }
await message.Channel.SendMessage( "unparsable"); await message.Channel.SendMessage( "unparsable");
return true; return true;
} }
} }

View File

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using vassago.Models; using vassago.Models;
[StaticPlz]
public class WishLuck : Behavior public class WishLuck : Behavior
{ {
public override string Name => "wish me luck"; public override string Name => "wish me luck";

View File

@ -29,7 +29,7 @@ public class DiscordInterface
}; };
public DiscordInterface() public DiscordInterface()
{ {
_db = Shared.dbContext; _db = new ChattingContext();
} }
public async Task Init(string token) public async Task Init(string token)
@ -41,6 +41,7 @@ public class DiscordInterface
Console.WriteLine(msg.ToString()); Console.WriteLine(msg.ToString());
return Task.CompletedTask; return Task.CompletedTask;
}; };
client.Connected += SelfConnected;
client.Ready += () => Task.Run(() => client.Ready += () => Task.Run(() =>
{ {
@ -78,10 +79,18 @@ public class DiscordInterface
await client.StartAsync(); await client.StartAsync();
} }
#pragma warning disable 4014 //the "you're not awaiting this" warning. yeah I know, that's the beauty of an async method lol private async Task SelfConnected()
#pragma warning disable 1998 //the "it's async but you're not awaiting anything". {
var selfUser = UpsertAccount(client.CurrentUser);
await _db.SaveChangesAsync();
Behaver.Instance.Selves.Add(selfUser);
}
#pragma warning disable 4014 //the "you're not awaiting this" warning. yeah I know, that's the beauty of an async method lol
#pragma warning disable 1998 //the "it's async but you're not awaiting anything".
private async Task MessageReceived(SocketMessage messageParam) private async Task MessageReceived(SocketMessage messageParam)
#pragma warning restore 1998 #pragma warning restore 1998
{ {
var suMessage = messageParam as SocketUserMessage; var suMessage = messageParam as SocketUserMessage;
if (suMessage == null) if (suMessage == null)
@ -99,7 +108,7 @@ public class DiscordInterface
m.MentionsMe = true; m.MentionsMe = true;
} }
// if ((suMessage.Author.Id != client.CurrentUser.Id)) // if ((suMessage.Author.Id != client.CurrentUser.Id))
{ {
if (await Behaver.Instance.ActOn(m)) if (await Behaver.Instance.ActOn(m))
{ {
@ -112,10 +121,10 @@ public class DiscordInterface
private void UserJoined(SocketGuildUser arg) private void 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 = UpsertUser(arg); var u = UpsertAccount(arg);
} }
private async Task ButtonHandler(SocketMessageComponent component) private async Task ButtonHandler(SocketMessageComponent component)
{ {
@ -192,14 +201,14 @@ public class DiscordInterface
m.Attachments.Add(UpsertAttachment(da)); m.Attachments.Add(UpsertAttachment(da));
} }
} }
m.Author = UpsertUser(dMessage.Author); m.Author = UpsertAccount(dMessage.Author);
m.Channel = UpsertChannel(dMessage.Channel); m.Channel = UpsertChannel(dMessage.Channel);
m.Content = dMessage.Content; m.Content = dMessage.Content;
m.ExternalId = dMessage.Id; m.ExternalId = dMessage.Id;
m.Timestamp = dMessage.EditedTimestamp ?? dMessage.CreatedAt; m.Timestamp = dMessage.EditedTimestamp ?? dMessage.CreatedAt;
if (dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) != null) if(dMessage.Author.Id != client.CurrentUser.Id && dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) != null)
{ {
m.MentionsMe = true; m.MentionsMe = true;
} }
@ -218,12 +227,17 @@ public class DiscordInterface
var c = _db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id); var c = _db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id);
//var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides //var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides
var preferredEmote = e; var preferredEmote = e;
Emote emote; Emoji emoji;
if(!Emote.TryParse(preferredEmote, out emote)) if (Emoji.TryParse(preferredEmote, out emoji))
{ {
if(preferredEmote == e) return msg.AddReactionAsync(emoji);
}
Emote emote;
if (!Emote.TryParse(preferredEmote, out emote))
{
if (preferredEmote == e)
Console.Error.WriteLine($"never heard of emote {e}"); Console.Error.WriteLine($"never heard of emote {e}");
return null; return Task.CompletedTask;
} }
return msg.AddReactionAsync(emote); return msg.AddReactionAsync(emote);
@ -294,7 +308,7 @@ public class DiscordInterface
c.SendFile = (f, t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; send file"); }; c.SendFile = (f, t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; send file"); };
return c; return c;
} }
internal Account UpsertUser(IUser user) internal Account UpsertAccount(IUser user)
{ {
var addPlease = false; var addPlease = false;
var u = _db.Users.FirstOrDefault(ui => ui.ExternalId == user.Id); var u = _db.Users.FirstOrDefault(ui => ui.ExternalId == user.Id);
@ -322,11 +336,11 @@ public class DiscordInterface
//c.OtherUsers = c.OtherUsers ?? new List<User>(); //c.OtherUsers = c.OtherUsers ?? new List<User>();
//c.OtherUsers = await channel.GetUsersAsync(); //c.OtherUsers = await channel.GetUsersAsync();
var dChannel = client.GetChannel(channel.ExternalId.Value); var dChannel = client.GetChannel(channel.ExternalId.Value);
if(dChannel is IGuild) if (dChannel is IGuild)
{ {
var guild = channel as IGuild; var guild = channel as IGuild;
} }
else if(dChannel is IGuildChannel) else if (dChannel is IGuildChannel)
{ {
var gc = dChannel as IGuildChannel; var gc = dChannel as IGuildChannel;
} }

View File

@ -23,10 +23,9 @@ namespace vassago
public async Task MainAsync() public async Task MainAsync()
{ {
Shared.DBConnectionString = config.DBConnectionString; Shared.DBConnectionString = config.DBConnectionString;
Shared.dbContext = new ChattingContext(); var dbc = new ChattingContext();
{ dbc.Database.EnsureCreated();
Shared.dbContext.Database.EnsureCreated();
}
Conversion.Converter.Load(config.ExchangePairsLocation); Conversion.Converter.Load(config.ExchangePairsLocation);
if(config.DiscordTokens.Any()) if(config.DiscordTokens.Any())
foreach(var dt in config.DiscordTokens) foreach(var dt in config.DiscordTokens)
@ -34,7 +33,7 @@ namespace vassago
var d = new DiscordInterface.DiscordInterface(); var d = new DiscordInterface.DiscordInterface();
await d.Init(dt); await d.Init(dt);
discords.Add(d); discords.Add(d);
} }
await Task.Delay(-1); await Task.Delay(-1);
} }

View File

@ -9,6 +9,5 @@ public static class Shared
{ {
public static Random r = new Random(); public static Random r = new Random();
public static string DBConnectionString { get; set; } public static string DBConnectionString { get; set; }
public static ChattingContext dbContext { get; set; }
public static HttpClient HttpClient { get; internal set; } = new HttpClient(); public static HttpClient HttpClient { get; internal set; } = new HttpClient();
} }