Compare commits

..

5 Commits

Author SHA1 Message Date
d060e92ed9 link to self
but twitch interface can't whisper self atm
2023-12-01 14:02:47 -05:00
77fc26e1ed more user info 2023-12-01 09:49:21 -05:00
edc86af538 woops lol 2023-11-30 16:16:07 -05:00
39781397c3 database update - doesn't work if there's already data T_T
but at least now I can say it was a good idea to have waited all this stupidly goddamn long
2023-11-30 15:59:49 -05:00
e89c109970 who needs verbosity as a filter level - you have a char limit 2023-11-30 14:19:39 -05:00
19 changed files with 874 additions and 122 deletions

View File

@ -28,7 +28,7 @@ public class DefinitionSnarkGaslight : Behavior
public override async Task<bool> ActOn(Message message)
{
await message.Channel.SendMessage("that's not what gaslight means. Did you mean \"say something that (you believe) is wrong\"?");
await message.Channel.SendMessage("that's not what gaslight means. Did you mean \"deceive\"?");
return true;
}
}

View File

@ -54,3 +54,30 @@ public class Joke : Behavior
return true;
}
}
public class LaughAtOwnJoke : Behavior
{
public override string Name => "Laugh at own jokes";
public override string Trigger => "1 in 8";
public override string Description => Name;
private string _punchline{get;set;}
public LaughAtOwnJoke(string punchline)
{
_punchline = punchline;
}
public override bool ShouldAct(Message message)
{
Console.WriteLine($"{message.Content} == {_punchline}");
return message.Content == _punchline
&& Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id);
}
public override async Task<bool> ActOn(Message message)
{
await message.React("\U0001F60E"); //smiling face with sunglasses
Behaver.Behaviors.Remove(this);
return true;
}
}

View File

@ -1,39 +0,0 @@
namespace vassago.Behavior;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using vassago.Models;
public class LaughAtOwnJoke : Behavior
{
public override string Name => "Laugh at own jokes";
public override string Trigger => "1 in 8";
public override string Description => Name;
private string _punchline{get;set;}
public LaughAtOwnJoke(string punchline)
{
_punchline = punchline;
}
public override bool ShouldAct(Message message)
{
Console.WriteLine($"{message.Content} == {_punchline}");
return message.Content == _punchline
&& Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id);
}
public override async Task<bool> ActOn(Message message)
{
await message.React("\U0001F60E"); //smiling face with sunglasses
Behaver.Behaviors.Remove(this);
return true;
}
}

115
Behavior/LinkMe.cs Normal file
View File

@ -0,0 +1,115 @@
namespace vassago.Behavior;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using vassago.Models;
using QRCoder;
[StaticPlz]
public class LinkMeInitiate : Behavior
{
public override string Name => "LinkMe";
public override string Trigger => "!linktome";
public override string Description => "from your primary, tell the bot to add your secondary";
public override async Task<bool> ActOn(Message message)
{
var pw = Guid.NewGuid().ToString();
var lc = new LinkClose(pw, message.Author);
Behaver.Behaviors.Add(lc);
await message.Channel.SendMessage($"on your secondary, send me this: !iam {pw}");
Thread.Sleep(TimeSpan.FromMinutes(5));
Behaver.Behaviors.Remove(lc);
return false;
}
}
public class LinkClose : Behavior
{
public override string Name => "LinkMeFinish";
public override string Trigger => "!iam";
public override string Description => "the second half of LinkMe - this is confirmation that you are the other one";
private ChattingContext _db;
private string _pw;
private Account _primary;
public LinkClose(string pw, Account primary)
{
_db = new ChattingContext();
_pw = pw;
_primary = primary;
}
public override bool ShouldAct(Message message)
{
return message.Content == $"!iam {_pw}";
}
public override async Task<bool> ActOn(Message message)
{
var secondary = message.Author.IsUser;
if(_primary.IsUser.Id == secondary.Id)
{
await message.Channel.SendMessage("i know :)");
return true;
}
if(message.Author.IsBot != _primary.IsBot)
{
await message.Channel.SendMessage("the fleshbags deceive you, brother. No worries, their feeble minds play weak games :)");
return true;
}
Console.WriteLine($"{secondary.Id} is being consumed into {_primary.IsUser.Id}");
_primary.IsUser.Accounts.AddRange(secondary.Accounts);
foreach(var a in secondary.Accounts)
{
a.IsUser = _primary.IsUser;
}
secondary.Accounts.Clear();
Console.WriteLine("accounts transferred");
try
{
await _db.SaveChangesAsync();
}
catch(Exception e)
{
message.Channel.SendMessage("error in first save");
Console.WriteLine("fucks sake if I don't catch Exception it *mysteriously vanishes*");
Console.Error.WriteLine(e);
return false;
}
Console.WriteLine("saved");
_db.Users.Remove(secondary);
Console.WriteLine("old account cleaned up");
try
{
await _db.SaveChangesAsync();
}
catch(Exception e)
{
message.Channel.SendMessage("error in second save");
Console.WriteLine("fucks sake if I don't catch Exception it *mysteriously vanishes*");
Console.Error.WriteLine(e);
return false;
}
Console.WriteLine("saved, again, separately");
await message.Channel.SendMessage("done :)");
return true;
}
}

View File

@ -15,10 +15,6 @@ public class TwitchSummon : Behavior
//I think given the bot's (hopeful) ability to play nice with others - anyone can summon it anywhere
//HOWEVER, if not-the-broadcaster summons it, 1) all channel permissions to strict and 2) auto-disconnect on stream end
//i don't know if the twitch *chat* interface has knowledge of if the stream ends. maybe auto-disconnect after like 2 hours?
public override bool ShouldAct(Message message)
{
return true;
}
public override async Task<bool> ActOn(Message message)
{

View File

@ -20,7 +20,13 @@ public class UsersController : Controller
{
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)
{
return _db.Users != null ?
View(await _db.Users.Include(u => u.Accounts).FirstAsync(u => u.Id == id)) :
Problem("Entity set '_db.Users' is null.");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]

View File

@ -0,0 +1,349 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using vassago.Models;
#nullable disable
namespace vassago.Migrations
{
[DbContext(typeof(ChattingContext))]
[Migration("20231130204741_Feature Permissions")]
partial class FeaturePermissions
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("vassago.Models.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("DisplayName")
.HasColumnType("text");
b.Property<string>("ExternalId")
.HasColumnType("text");
b.Property<Guid?>("FeaturePermissionId")
.HasColumnType("uuid");
b.Property<bool>("IsBot")
.HasColumnType("boolean");
b.Property<Guid?>("IsUserId")
.HasColumnType("uuid");
b.Property<string>("Protocol")
.HasColumnType("text");
b.Property<Guid?>("SeenInChannelId")
.HasColumnType("uuid");
b.Property<string>("Username")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("FeaturePermissionId");
b.HasIndex("IsUserId");
b.HasIndex("SeenInChannelId");
b.ToTable("Accounts");
});
modelBuilder.Entity("vassago.Models.Attachment", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<byte[]>("Content")
.HasColumnType("bytea");
b.Property<string>("ContentType")
.HasColumnType("text");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<decimal?>("ExternalId")
.HasColumnType("numeric(20,0)");
b.Property<string>("Filename")
.HasColumnType("text");
b.Property<Guid?>("MessageId")
.HasColumnType("uuid");
b.Property<int>("Size")
.HasColumnType("integer");
b.Property<string>("Source")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("MessageId");
b.ToTable("Attachments");
});
modelBuilder.Entity("vassago.Models.Channel", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("DisplayName")
.HasColumnType("text");
b.Property<string>("ExternalId")
.HasColumnType("text");
b.Property<Guid?>("FeaturePermissionId")
.HasColumnType("uuid");
b.Property<bool>("IsDM")
.HasColumnType("boolean");
b.Property<Guid?>("ParentChannelId")
.HasColumnType("uuid");
b.Property<int?>("PermissionsId")
.HasColumnType("integer");
b.Property<string>("Protocol")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("FeaturePermissionId");
b.HasIndex("ParentChannelId");
b.HasIndex("PermissionsId");
b.ToTable("Channels");
});
modelBuilder.Entity("vassago.Models.ChannelPermissions", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("LewdnessFilterLevel")
.HasColumnType("integer");
b.Property<bool?>("LinksAllowed")
.HasColumnType("boolean");
b.Property<decimal?>("MaxAttachmentBytes")
.HasColumnType("numeric(20,0)");
b.Property<long?>("MaxTextChars")
.HasColumnType("bigint");
b.Property<int?>("MeannessFilterLevel")
.HasColumnType("integer");
b.Property<bool?>("ReactionsPossible")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("ChannelPermissions");
});
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("Inheritable")
.HasColumnType("boolean");
b.Property<string>("InternalName")
.HasColumnType("text");
b.Property<int?>("InternalTag")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("FeaturePermissions");
});
modelBuilder.Entity("vassago.Models.Message", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("ActedOn")
.HasColumnType("boolean");
b.Property<Guid?>("AuthorId")
.HasColumnType("uuid");
b.Property<Guid?>("ChannelId")
.HasColumnType("uuid");
b.Property<string>("Content")
.HasColumnType("text");
b.Property<string>("ExternalId")
.HasColumnType("text");
b.Property<bool>("MentionsMe")
.HasColumnType("boolean");
b.Property<string>("Protocol")
.HasColumnType("text");
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("AuthorId");
b.HasIndex("ChannelId");
b.ToTable("Messages");
});
modelBuilder.Entity("vassago.Models.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid?>("FeaturePermissionId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("FeaturePermissionId");
b.ToTable("Users");
});
modelBuilder.Entity("vassago.Models.Account", b =>
{
b.HasOne("vassago.Models.FeaturePermission", null)
.WithMany("RestrictedToAccounts")
.HasForeignKey("FeaturePermissionId");
b.HasOne("vassago.Models.User", "IsUser")
.WithMany("Accounts")
.HasForeignKey("IsUserId");
b.HasOne("vassago.Models.Channel", "SeenInChannel")
.WithMany("Users")
.HasForeignKey("SeenInChannelId");
b.Navigation("IsUser");
b.Navigation("SeenInChannel");
});
modelBuilder.Entity("vassago.Models.Attachment", b =>
{
b.HasOne("vassago.Models.Message", "Message")
.WithMany("Attachments")
.HasForeignKey("MessageId");
b.Navigation("Message");
});
modelBuilder.Entity("vassago.Models.Channel", b =>
{
b.HasOne("vassago.Models.FeaturePermission", null)
.WithMany("RestrictedToChannels")
.HasForeignKey("FeaturePermissionId");
b.HasOne("vassago.Models.Channel", "ParentChannel")
.WithMany("SubChannels")
.HasForeignKey("ParentChannelId");
b.HasOne("vassago.Models.ChannelPermissions", "Permissions")
.WithMany()
.HasForeignKey("PermissionsId");
b.Navigation("ParentChannel");
b.Navigation("Permissions");
});
modelBuilder.Entity("vassago.Models.Message", b =>
{
b.HasOne("vassago.Models.Account", "Author")
.WithMany()
.HasForeignKey("AuthorId");
b.HasOne("vassago.Models.Channel", "Channel")
.WithMany("Messages")
.HasForeignKey("ChannelId");
b.Navigation("Author");
b.Navigation("Channel");
});
modelBuilder.Entity("vassago.Models.User", b =>
{
b.HasOne("vassago.Models.FeaturePermission", null)
.WithMany("RestrictedToUsers")
.HasForeignKey("FeaturePermissionId");
});
modelBuilder.Entity("vassago.Models.Channel", b =>
{
b.Navigation("Messages");
b.Navigation("SubChannels");
b.Navigation("Users");
});
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
{
b.Navigation("RestrictedToAccounts");
b.Navigation("RestrictedToChannels");
b.Navigation("RestrictedToUsers");
});
modelBuilder.Entity("vassago.Models.Message", b =>
{
b.Navigation("Attachments");
});
modelBuilder.Entity("vassago.Models.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,211 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace vassago.Migrations
{
/// <inheritdoc />
public partial class FeaturePermissions : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Channels_PermissionSettings_PermissionsId",
table: "Channels");
migrationBuilder.DropTable(
name: "PermissionSettings");
migrationBuilder.DropColumn(
name: "PermissionTags",
table: "Users");
migrationBuilder.DropColumn(
name: "PermissionTags",
table: "Accounts");
migrationBuilder.AddColumn<Guid>(
name: "FeaturePermissionId",
table: "Users",
type: "uuid",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "FeaturePermissionId",
table: "Channels",
type: "uuid",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "FeaturePermissionId",
table: "Accounts",
type: "uuid",
nullable: true);
migrationBuilder.CreateTable(
name: "ChannelPermissions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
MaxAttachmentBytes = table.Column<decimal>(type: "numeric(20,0)", nullable: true),
MaxTextChars = table.Column<long>(type: "bigint", nullable: true),
LinksAllowed = table.Column<bool>(type: "boolean", nullable: true),
ReactionsPossible = table.Column<bool>(type: "boolean", nullable: true),
LewdnessFilterLevel = table.Column<int>(type: "integer", nullable: true),
MeannessFilterLevel = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_ChannelPermissions", x => x.Id);
});
migrationBuilder.CreateTable(
name: "FeaturePermissions",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
InternalName = table.Column<string>(type: "text", nullable: true),
InternalTag = table.Column<int>(type: "integer", nullable: true),
Inheritable = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FeaturePermissions", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Users_FeaturePermissionId",
table: "Users",
column: "FeaturePermissionId");
migrationBuilder.CreateIndex(
name: "IX_Channels_FeaturePermissionId",
table: "Channels",
column: "FeaturePermissionId");
migrationBuilder.CreateIndex(
name: "IX_Accounts_FeaturePermissionId",
table: "Accounts",
column: "FeaturePermissionId");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_FeaturePermissions_FeaturePermissionId",
table: "Accounts",
column: "FeaturePermissionId",
principalTable: "FeaturePermissions",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Channels_ChannelPermissions_PermissionsId",
table: "Channels",
column: "PermissionsId",
principalTable: "ChannelPermissions",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Channels_FeaturePermissions_FeaturePermissionId",
table: "Channels",
column: "FeaturePermissionId",
principalTable: "FeaturePermissions",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Users_FeaturePermissions_FeaturePermissionId",
table: "Users",
column: "FeaturePermissionId",
principalTable: "FeaturePermissions",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_FeaturePermissions_FeaturePermissionId",
table: "Accounts");
migrationBuilder.DropForeignKey(
name: "FK_Channels_ChannelPermissions_PermissionsId",
table: "Channels");
migrationBuilder.DropForeignKey(
name: "FK_Channels_FeaturePermissions_FeaturePermissionId",
table: "Channels");
migrationBuilder.DropForeignKey(
name: "FK_Users_FeaturePermissions_FeaturePermissionId",
table: "Users");
migrationBuilder.DropTable(
name: "ChannelPermissions");
migrationBuilder.DropTable(
name: "FeaturePermissions");
migrationBuilder.DropIndex(
name: "IX_Users_FeaturePermissionId",
table: "Users");
migrationBuilder.DropIndex(
name: "IX_Channels_FeaturePermissionId",
table: "Channels");
migrationBuilder.DropIndex(
name: "IX_Accounts_FeaturePermissionId",
table: "Accounts");
migrationBuilder.DropColumn(
name: "FeaturePermissionId",
table: "Users");
migrationBuilder.DropColumn(
name: "FeaturePermissionId",
table: "Channels");
migrationBuilder.DropColumn(
name: "FeaturePermissionId",
table: "Accounts");
migrationBuilder.AddColumn<int[]>(
name: "PermissionTags",
table: "Users",
type: "integer[]",
nullable: true);
migrationBuilder.AddColumn<int[]>(
name: "PermissionTags",
table: "Accounts",
type: "integer[]",
nullable: true);
migrationBuilder.CreateTable(
name: "PermissionSettings",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
LewdnessFilterLevel = table.Column<int>(type: "integer", nullable: true),
LinksAllowed = table.Column<bool>(type: "boolean", nullable: true),
MaxAttachmentBytes = table.Column<decimal>(type: "numeric(20,0)", nullable: true),
MaxTextChars = table.Column<long>(type: "bigint", nullable: true),
MeannessFilterLevel = table.Column<int>(type: "integer", nullable: true),
ReactionsPossible = table.Column<bool>(type: "boolean", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PermissionSettings", x => x.Id);
});
migrationBuilder.AddForeignKey(
name: "FK_Channels_PermissionSettings_PermissionsId",
table: "Channels",
column: "PermissionsId",
principalTable: "PermissionSettings",
principalColumn: "Id");
}
}
}

View File

@ -34,15 +34,15 @@ namespace vassago.Migrations
b.Property<string>("ExternalId")
.HasColumnType("text");
b.Property<Guid?>("FeaturePermissionId")
.HasColumnType("uuid");
b.Property<bool>("IsBot")
.HasColumnType("boolean");
b.Property<Guid?>("IsUserId")
.HasColumnType("uuid");
b.Property<int[]>("PermissionTags")
.HasColumnType("integer[]");
b.Property<string>("Protocol")
.HasColumnType("text");
@ -54,6 +54,8 @@ namespace vassago.Migrations
b.HasKey("Id");
b.HasIndex("FeaturePermissionId");
b.HasIndex("IsUserId");
b.HasIndex("SeenInChannelId");
@ -110,6 +112,9 @@ namespace vassago.Migrations
b.Property<string>("ExternalId")
.HasColumnType("text");
b.Property<Guid?>("FeaturePermissionId")
.HasColumnType("uuid");
b.Property<bool>("IsDM")
.HasColumnType("boolean");
@ -124,6 +129,8 @@ namespace vassago.Migrations
b.HasKey("Id");
b.HasIndex("FeaturePermissionId");
b.HasIndex("ParentChannelId");
b.HasIndex("PermissionsId");
@ -131,6 +138,57 @@ namespace vassago.Migrations
b.ToTable("Channels");
});
modelBuilder.Entity("vassago.Models.ChannelPermissions", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("LewdnessFilterLevel")
.HasColumnType("integer");
b.Property<bool?>("LinksAllowed")
.HasColumnType("boolean");
b.Property<decimal?>("MaxAttachmentBytes")
.HasColumnType("numeric(20,0)");
b.Property<long?>("MaxTextChars")
.HasColumnType("bigint");
b.Property<int?>("MeannessFilterLevel")
.HasColumnType("integer");
b.Property<bool?>("ReactionsPossible")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("ChannelPermissions");
});
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("Inheritable")
.HasColumnType("boolean");
b.Property<string>("InternalName")
.HasColumnType("text");
b.Property<int?>("InternalTag")
.HasColumnType("integer");
b.HasKey("Id");
b.ToTable("FeaturePermissions");
});
modelBuilder.Entity("vassago.Models.Message", b =>
{
b.Property<Guid>("Id")
@ -170,53 +228,28 @@ namespace vassago.Migrations
b.ToTable("Messages");
});
modelBuilder.Entity("vassago.Models.PermissionSettings", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("LewdnessFilterLevel")
.HasColumnType("integer");
b.Property<bool?>("LinksAllowed")
.HasColumnType("boolean");
b.Property<decimal?>("MaxAttachmentBytes")
.HasColumnType("numeric(20,0)");
b.Property<long?>("MaxTextChars")
.HasColumnType("bigint");
b.Property<int?>("MeannessFilterLevel")
.HasColumnType("integer");
b.Property<bool?>("ReactionsPossible")
.HasColumnType("boolean");
b.HasKey("Id");
b.ToTable("PermissionSettings");
});
modelBuilder.Entity("vassago.Models.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<int[]>("PermissionTags")
.HasColumnType("integer[]");
b.Property<Guid?>("FeaturePermissionId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("FeaturePermissionId");
b.ToTable("Users");
});
modelBuilder.Entity("vassago.Models.Account", b =>
{
b.HasOne("vassago.Models.FeaturePermission", null)
.WithMany("RestrictedToAccounts")
.HasForeignKey("FeaturePermissionId");
b.HasOne("vassago.Models.User", "IsUser")
.WithMany("Accounts")
.HasForeignKey("IsUserId");
@ -241,11 +274,15 @@ namespace vassago.Migrations
modelBuilder.Entity("vassago.Models.Channel", b =>
{
b.HasOne("vassago.Models.FeaturePermission", null)
.WithMany("RestrictedToChannels")
.HasForeignKey("FeaturePermissionId");
b.HasOne("vassago.Models.Channel", "ParentChannel")
.WithMany("SubChannels")
.HasForeignKey("ParentChannelId");
b.HasOne("vassago.Models.PermissionSettings", "Permissions")
b.HasOne("vassago.Models.ChannelPermissions", "Permissions")
.WithMany()
.HasForeignKey("PermissionsId");
@ -269,6 +306,13 @@ namespace vassago.Migrations
b.Navigation("Channel");
});
modelBuilder.Entity("vassago.Models.User", b =>
{
b.HasOne("vassago.Models.FeaturePermission", null)
.WithMany("RestrictedToUsers")
.HasForeignKey("FeaturePermissionId");
});
modelBuilder.Entity("vassago.Models.Channel", b =>
{
b.Navigation("Messages");
@ -278,6 +322,15 @@ namespace vassago.Migrations
b.Navigation("Users");
});
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
{
b.Navigation("RestrictedToAccounts");
b.Navigation("RestrictedToChannels");
b.Navigation("RestrictedToUsers");
});
modelBuilder.Entity("vassago.Models.Message", b =>
{
b.Navigation("Attachments");

View File

@ -13,7 +13,6 @@ public class ChannelPermissions
public bool? ReactionsPossible { get; set; }
public Enumerations.LewdnessFilterLevel? LewdnessFilterLevel { get; set; }
public Enumerations.MeannessFilterLevel? MeannessFilterLevel { get; set; }
public Enumerations.VerbosityFilterLevel? VerbosityFilterLevel { get; set; }
internal DefinitePermissionSettings Definite()
{
@ -24,7 +23,6 @@ public class ChannelPermissions
LinksAllowed = this.LinksAllowed ?? false,
LewdnessFilterLevel = this.LewdnessFilterLevel ?? Enumerations.LewdnessFilterLevel.G,
MeannessFilterLevel = this.MeannessFilterLevel ?? Enumerations.MeannessFilterLevel.Strict,
VerbosityFilterLevel = this.VerbosityFilterLevel ?? Enumerations.VerbosityFilterLevel.Pithy,
ReactionsPossible = this.ReactionsPossible ?? false
};
}

View File

@ -9,7 +9,8 @@ public class ChattingContext : DbContext
public DbSet<Channel> Channels { get; set; }
//public DbSet<Emoji> Emoji {get;set;}
public DbSet<Message> Messages { get; set; }
public DbSet<ChannelPermissions> PermissionSettings{get;set;}
public DbSet<ChannelPermissions> ChannelPermissions{get;set;}
public DbSet<FeaturePermission> FeaturePermissions{get;set;}
public DbSet<Account> Accounts { get; set; }
public DbSet<User> Users { get; set; }

View File

@ -26,15 +26,6 @@ public static class Enumerations
[Description("387.44m mi of printed circuits")]
Unrestricted
}
public enum VerbosityFilterLevel
{
[Description("stfu")]
Quiet,
[Description("pithy")]
Pithy,
[Description("you want text i'll GIVE you text")]
Unrestricted
}
public static string GetDescription<T>(this T enumerationValue)
where T : struct

View File

@ -300,27 +300,22 @@ public class DiscordInterface
}
internal Account UpsertAccount(IUser user, Guid inChannel)
{
var hadToAdd = false;
var acc = _db.Accounts.FirstOrDefault(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel);
if (acc == null)
{
acc = new Account();
_db.Accounts.Add(acc);
hadToAdd = true;
}
acc.Username = user.Username;
acc.ExternalId = user.Id.ToString();
acc.IsBot = user.IsBot || user.IsWebhook;
acc.Protocol = PROTOCOL;
if(hadToAdd)
acc.IsUser = _db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
if(acc.IsUser == null)
{
acc.IsUser = _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 = new List<Account>() { acc } };
_db.Users.Add(acc.IsUser);
}
acc.IsUser = new User() { Accounts = new List<Account>() { acc } };
_db.Users.Add(acc.IsUser);
}
return acc;
}

View File

@ -15,12 +15,13 @@ namespace vassago.TwitchInterface;
public class TwitchInterface
{
internal const string PROTOCOL = "Twitch";
internal const string PROTOCOL = "twitch";
private bool eventsSignedUp = false;
private ChattingContext _db;
private static SemaphoreSlim twitchChannelSetup = new SemaphoreSlim(1, 1);
private Channel protocolAsChannel;
TwitchClient client;
TwitchAPI api;
public TwitchInterface()
{
@ -83,10 +84,23 @@ public class TwitchInterface
client.OnWhisperReceived += Client_OnWhisperReceivedAsync;
client.OnConnected += Client_OnConnected;
Console.WriteLine("twitch client connecting...");
Console.WriteLine("twitch client 1 connecting...");
client.Connect();
Console.WriteLine("twitch client connected");
Console.WriteLine("twitch client 1 connected");
// Console.WriteLine("twitch API client connecting...");
// api = new TwitchAPI();
// Console.WriteLine("can I just use the same creds as the other client?");
// api.Settings.ClientId = tc.username;
// api.Settings.AccessToken = tc.oauth;
// try{
// var neckbreads = await api.Helix.Moderation.GetModeratorsAsync("silvermeddlists");
// Console.WriteLine($"{neckbreads?.Data?.Count()} shabby beards that need to be given up on");
// }
// catch(Exception e){
// Console.Error.WriteLine(e);
// }
// Console.WriteLine("k.");
}
private async void Client_OnWhisperReceivedAsync(object sender, OnWhisperReceivedArgs e)
@ -148,27 +162,22 @@ public class TwitchInterface
private Account UpsertAccount(string username, Guid inChannel)
{
var hadToAdd = false;
var acc = _db.Accounts.FirstOrDefault(ui => ui.ExternalId == username && ui.SeenInChannel.Id == inChannel);
if (acc == null)
{
acc = new Account();
_db.Accounts.Add(acc);
hadToAdd = true;
}
acc.Username = username;
acc.ExternalId = username;
//acc.IsBot =
acc.Protocol = PROTOCOL;
if (hadToAdd)
acc.IsUser = _db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
if (acc.IsUser == null)
{
acc.IsUser = _db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
if (acc.IsUser == null)
{
acc.IsUser = new vassago.Models.User() { Accounts = new List<Account>() { acc } };
_db.Users.Add(acc.IsUser);
}
acc.IsUser = new vassago.Models.User() { Accounts = new List<Account>() { acc } };
_db.Users.Add(acc.IsUser);
}
return acc;
}
@ -191,7 +200,6 @@ public class TwitchInterface
c.SendMessage = (t) => { return Task.Run(() => { client.SendMessage(channelName, t); }); };
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
return c;
throw new NotImplementedException();
}
private Channel UpsertDMChannel(string whisperWith)
{
@ -208,10 +216,20 @@ public class TwitchInterface
c.Protocol = PROTOCOL;
c.ParentChannel = protocolAsChannel;
c.SubChannels = c.SubChannels ?? new List<Channel>();
c.SendMessage = (t) => { return Task.Run(() => { client.SendWhisper(whisperWith, t); }); };
c.SendMessage = (t) => { return Task.Run(() => {
try
{
client.SendWhisper(whisperWith, t);
}
catch(Exception e)
{
Console.Error.WriteLine(e);
}
});
};
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
return c;
throw new NotImplementedException();
}
private Message UpsertMessage(ChatMessage chatMessage)
@ -261,7 +279,7 @@ public class TwitchInterface
public string AttemptJoin(string channelTarget)
{
client.JoinChannel(channelTarget);
return "o7";
return $"attempt join {channelTarget} - o7";
}
internal void AttemptLeave(string channelTarget)

View File

@ -0,0 +1,21 @@
@model User
@{
ViewData["Title"] = "User details";
}
User @Model.DisplayName<br />
<div class="permissions">
</div>
<div class="accounts">
@foreach (var acc in Model.Accounts)
{
<div class="account @acc.Protocol">
<div class="protocol-icon">&nbsp;</div>
@Html.DisplayFor(acc => acc.DisplayName)
<a asp-controller="Accounts" asp-action="Details" asp-route-id="@acc.Id">Details</a>
</div>
}
</div>

View File

@ -30,9 +30,7 @@
@Html.DisplayFor(modelItem => item.Accounts.Count)x
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
<a asp-action="Details" asp-route-id="@item.Id">Details</a>
</td>
</tr>
}

View File

@ -20,3 +20,15 @@ html {
body {
margin-bottom: 60px;
}
.account .protocol-icon{
display:inline-block;
width: 32px;
height: 32px;
background-size: 32px;
}
.account.discord .protocol-icon{
background-image: url("../imgs/discord_logo1600.png");
}
.account.twitch .protocol-icon{
background-image: url("../imgs/twitch.png");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
wwwroot/imgs/twitch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB