More DB staff and house keeping and better emoji
This commit is contained in:
@@ -6,14 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Migrations\20190615141205_Inital.cs" />
|
||||
<Compile Remove="Migrations\20190615141205_Inital.Designer.cs" />
|
||||
<Compile Remove="Migrations\20190615203117_Inital.cs" />
|
||||
<Compile Remove="Migrations\20190615203117_Inital.Designer.cs" />
|
||||
<Compile Remove="Migrations\20190616081659_InitialSetup.cs" />
|
||||
<Compile Remove="Migrations\20190616081659_InitialSetup.Designer.cs" />
|
||||
<Compile Remove="Migrations\20190616175542_ForeginKeyFix.cs" />
|
||||
<Compile Remove="Migrations\20190616175542_ForeginKeyFix.Designer.cs" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -28,7 +21,6 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
|
||||
<PackageReference Include="Unicode.net" Version="0.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -37,8 +29,4 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Migrations\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
140
EventBot/Migrations/Sqlite/20190618165006_InitialDatabase.Designer.cs
generated
Normal file
140
EventBot/Migrations/Sqlite/20190618165006_InitialDatabase.Designer.cs
generated
Normal file
@@ -0,0 +1,140 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using EventBot.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace EventBot.Migrations.Sqlite
|
||||
{
|
||||
[DbContext(typeof(SqliteDatabaseService))]
|
||||
[Migration("20190618165006_InitialDatabase")]
|
||||
partial class InitialDatabase
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.Event", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("MessageChannelId");
|
||||
|
||||
b.Property<ulong>("MessageId");
|
||||
|
||||
b.Property<DateTime>("Opened");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("Events");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventParticipant", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("EventId");
|
||||
|
||||
b.Property<int>("EventRoleId");
|
||||
|
||||
b.Property<string>("UserData");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EventId");
|
||||
|
||||
b.HasIndex("EventRoleId");
|
||||
|
||||
b.ToTable("EventParticipants");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("Emote");
|
||||
|
||||
b.Property<int>("EventId");
|
||||
|
||||
b.Property<int>("MaxParticipants");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EventId");
|
||||
|
||||
b.ToTable("EventRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.GuildConfig", b =>
|
||||
{
|
||||
b.Property<ulong>("GuildId")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("EventRoleConfirmationChannelId");
|
||||
|
||||
b.Property<ulong>("ParticipantRoleId");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("GuildId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.Event", b =>
|
||||
{
|
||||
b.HasOne("EventBot.Entities.GuildConfig", "Guild")
|
||||
.WithMany("Events")
|
||||
.HasForeignKey("GuildId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventParticipant", b =>
|
||||
{
|
||||
b.HasOne("EventBot.Entities.Event", "Event")
|
||||
.WithMany("Participants")
|
||||
.HasForeignKey("EventId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("EventBot.Entities.EventRole", "Role")
|
||||
.WithMany("Participants")
|
||||
.HasForeignKey("EventRoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventRole", b =>
|
||||
{
|
||||
b.HasOne("EventBot.Entities.Event", "Event")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("EventId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
138
EventBot/Migrations/Sqlite/20190618165006_InitialDatabase.cs
Normal file
138
EventBot/Migrations/Sqlite/20190618165006_InitialDatabase.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace EventBot.Migrations.Sqlite
|
||||
{
|
||||
public partial class InitialDatabase : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GuildConfigs",
|
||||
columns: table => new
|
||||
{
|
||||
GuildId = table.Column<ulong>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Prefix = table.Column<string>(nullable: true),
|
||||
EventRoleConfirmationChannelId = table.Column<ulong>(nullable: false),
|
||||
ParticipantRoleId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GuildConfigs", x => x.GuildId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Events",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Title = table.Column<string>(nullable: true),
|
||||
Description = table.Column<string>(nullable: true),
|
||||
Active = table.Column<bool>(nullable: false),
|
||||
MessageId = table.Column<ulong>(nullable: false),
|
||||
MessageChannelId = table.Column<ulong>(nullable: false),
|
||||
Opened = table.Column<DateTime>(nullable: false),
|
||||
Type = table.Column<int>(nullable: false),
|
||||
GuildId = table.Column<ulong>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Events", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Events_GuildConfigs_GuildId",
|
||||
column: x => x.GuildId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "GuildId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EventRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Title = table.Column<string>(nullable: true),
|
||||
Description = table.Column<string>(nullable: true),
|
||||
Emote = table.Column<string>(nullable: true),
|
||||
MaxParticipants = table.Column<int>(nullable: false),
|
||||
EventId = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EventRoles", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_EventRoles_Events_EventId",
|
||||
column: x => x.EventId,
|
||||
principalTable: "Events",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EventParticipants",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
EventRoleId = table.Column<int>(nullable: false),
|
||||
EventId = table.Column<int>(nullable: false),
|
||||
UserId = table.Column<ulong>(nullable: false),
|
||||
UserData = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EventParticipants", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_EventParticipants_Events_EventId",
|
||||
column: x => x.EventId,
|
||||
principalTable: "Events",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_EventParticipants_EventRoles_EventRoleId",
|
||||
column: x => x.EventRoleId,
|
||||
principalTable: "EventRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EventParticipants_EventId",
|
||||
table: "EventParticipants",
|
||||
column: "EventId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EventParticipants_EventRoleId",
|
||||
table: "EventParticipants",
|
||||
column: "EventRoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EventRoles_EventId",
|
||||
table: "EventRoles",
|
||||
column: "EventId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Events_GuildId",
|
||||
table: "Events",
|
||||
column: "GuildId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "EventParticipants");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "EventRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Events");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "GuildConfigs");
|
||||
}
|
||||
}
|
||||
}
|
138
EventBot/Migrations/Sqlite/SqliteDatabaseServiceModelSnapshot.cs
Normal file
138
EventBot/Migrations/Sqlite/SqliteDatabaseServiceModelSnapshot.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using EventBot.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace EventBot.Migrations.Sqlite
|
||||
{
|
||||
[DbContext(typeof(SqliteDatabaseService))]
|
||||
partial class SqliteDatabaseServiceModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.Event", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("MessageChannelId");
|
||||
|
||||
b.Property<ulong>("MessageId");
|
||||
|
||||
b.Property<DateTime>("Opened");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("Events");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventParticipant", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("EventId");
|
||||
|
||||
b.Property<int>("EventRoleId");
|
||||
|
||||
b.Property<string>("UserData");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EventId");
|
||||
|
||||
b.HasIndex("EventRoleId");
|
||||
|
||||
b.ToTable("EventParticipants");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("Emote");
|
||||
|
||||
b.Property<int>("EventId");
|
||||
|
||||
b.Property<int>("MaxParticipants");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EventId");
|
||||
|
||||
b.ToTable("EventRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.GuildConfig", b =>
|
||||
{
|
||||
b.Property<ulong>("GuildId")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("EventRoleConfirmationChannelId");
|
||||
|
||||
b.Property<ulong>("ParticipantRoleId");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("GuildId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.Event", b =>
|
||||
{
|
||||
b.HasOne("EventBot.Entities.GuildConfig", "Guild")
|
||||
.WithMany("Events")
|
||||
.HasForeignKey("GuildId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventParticipant", b =>
|
||||
{
|
||||
b.HasOne("EventBot.Entities.Event", "Event")
|
||||
.WithMany("Participants")
|
||||
.HasForeignKey("EventId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("EventBot.Entities.EventRole", "Role")
|
||||
.WithMany("Participants")
|
||||
.HasForeignKey("EventRoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("EventBot.Entities.EventRole", b =>
|
||||
{
|
||||
b.HasOne("EventBot.Entities.Event", "Event")
|
||||
.WithMany("Roles")
|
||||
.HasForeignKey("EventId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
79
EventBot/Misc/EmoteHelper.cs
Normal file
79
EventBot/Misc/EmoteHelper.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Discord;
|
||||
using System;
|
||||
|
||||
namespace EventBot.Services
|
||||
{
|
||||
|
||||
public static class EmoteHelper
|
||||
{
|
||||
//private IEnumerable<string> emoji;
|
||||
|
||||
private static readonly int[] EmojiRanges =
|
||||
{
|
||||
0x1F600,0x1F64F, // Emoticons
|
||||
0x1F300,0x1F5FF, // Misc Symbols and Pictographs
|
||||
0x1F680,0x1F6FF, // Transport and Map
|
||||
0x1F1E6,0x1F1FF, // Regional country flags
|
||||
0x2600,0x26FF, // Misc symbols
|
||||
0x2700,0x27BF, // Dingbats
|
||||
0xE0020,0xE007F, // Tags
|
||||
0xFE00,0xFE0F, // Variation Selectors
|
||||
0x1F900,0x1F9FF, // Supplemental Symbols and Pictographs
|
||||
0x1F018,0x1F270, // Various asian characters
|
||||
0x238C,0x2454, // Misc items
|
||||
0x20D0,0x20FF // Combining Diacritical Marks for Symbols
|
||||
};
|
||||
|
||||
public static bool TryParse(string input, out IEmote emote)
|
||||
{
|
||||
if(Emote.TryParse(input, out Emote parsedEmote))
|
||||
{
|
||||
emote = parsedEmote;
|
||||
return true;
|
||||
}
|
||||
if(isEmoji(input))
|
||||
{
|
||||
emote = new Emoji(input);
|
||||
return true;
|
||||
}
|
||||
emote = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEmote Parse(string input)
|
||||
{
|
||||
if (!TryParse(input, out IEmote parsed))
|
||||
throw new ArgumentException("Failed to parse emote.");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public static bool isEmoji(string input)
|
||||
{
|
||||
if (input.Length % 2 == 1) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < input.Length; i += 2)
|
||||
{
|
||||
if (!char.IsSurrogatePair(input[i], input[i + 1]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var utf32 = char.ConvertToUtf32(input[i], input[i + 1]);
|
||||
if (utf32 != 0x200D && !isEmojiChar(utf32))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static bool isEmojiChar(int u32)
|
||||
{;
|
||||
for (int i = 0; i < EmojiRanges.Length; i+= 2)
|
||||
if (u32 >= EmojiRanges[i] && u32 <= EmojiRanges[i + 1])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -18,9 +18,9 @@ namespace EventBot.Misc
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.UnmetPrecondition, "Events are avaivable only inside guild context."));
|
||||
Event ev;
|
||||
if (input == null)
|
||||
ev = events.FindEventBy(context.Guild);
|
||||
ev = events.FindEventBy(context.Guild, true);
|
||||
else if (int.TryParse(input, out int id))
|
||||
ev = events.FindEventBy(context.Guild, id);
|
||||
ev = events.FindEventBy(context.Guild, id, true);
|
||||
else
|
||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Event id is not a number."));
|
||||
|
||||
|
@@ -9,6 +9,7 @@ using System.Linq;
|
||||
using EventBot.Entities;
|
||||
using Discord.WebSocket;
|
||||
using NeoSmart.Unicode;
|
||||
using Discord.Addons.Interactive;
|
||||
|
||||
namespace EventBot.Modules
|
||||
{
|
||||
@@ -53,16 +54,14 @@ namespace EventBot.Modules
|
||||
[RequireUserPermission(GuildPermission.Administrator, Group = "Permission")]
|
||||
[RequireOwner(Group = "Permission")]
|
||||
[Group("event")]
|
||||
public class EventManagementModule : ModuleBase<SocketCommandContext>
|
||||
public class EventManagementModule : InteractiveBase<SocketCommandContext>
|
||||
{
|
||||
private readonly EventManagementService _events;
|
||||
private readonly DatabaseService _database;
|
||||
private readonly EmoteService _emotes;
|
||||
public EventManagementModule(EventManagementService events, DatabaseService database, EmoteService emotes)
|
||||
public EventManagementModule(EventManagementService events, DatabaseService database)
|
||||
{
|
||||
_events = events;
|
||||
_database = database;
|
||||
_emotes = emotes;
|
||||
}
|
||||
|
||||
[Command("config logchannel")]
|
||||
@@ -128,6 +127,8 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("Unable to locate any events for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
@event.Title = title;
|
||||
await _database.SaveChangesAsync();
|
||||
await ReplyAsync($"Updated event(`{@event.Id}`) title to `{@event.Title}`");
|
||||
@@ -143,6 +144,8 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("Unable to locate any events for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
@event.Description = description;
|
||||
await _database.SaveChangesAsync();
|
||||
await ReplyAsync($"Updated event(`{@event.Id}`) description to `{@event.Description}`");
|
||||
@@ -161,6 +164,8 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("Unable to locate any events for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
if (@event.MessageId != 0 && @event.Type != type)
|
||||
throw new Exception("Can't change event registration type when it's open for registration. Maube you meant to set type to `Unspecified` (-1)");
|
||||
if(@event.Type != type)
|
||||
@@ -183,11 +188,13 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("Unable to locate any events for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
if (@event.Roles != null && @event.Roles.Count >= 20)
|
||||
throw new Exception("There are too many roles for this event.");
|
||||
if(@event.MessageId != 0)
|
||||
throw new Exception("Can't add new roles to event with open reigstration.");
|
||||
if (!_emotes.TryParse(emote, out IEmote parsedEmote))
|
||||
if (!EmoteHelper.TryParse(emote, out IEmote parsedEmote))
|
||||
throw new ArgumentException("Invalid emote provided.");
|
||||
if(@event.Roles != null && @event.Roles.Count(r => r.Emote == parsedEmote.ToString()) > 0)
|
||||
throw new ArgumentException("This emote is already used by other role.");
|
||||
@@ -212,6 +219,8 @@ namespace EventBot.Modules
|
||||
{
|
||||
if(eventRole == null)
|
||||
throw new Exception("Please provide correct role.");
|
||||
if (!eventRole.Event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
eventRole.Title = title;
|
||||
var s = _database.SaveChangesAsync();
|
||||
await ReplyAsync($"Updated event role `{eventRole.Id}` title to `{eventRole.Title}`");
|
||||
@@ -227,6 +236,8 @@ namespace EventBot.Modules
|
||||
{
|
||||
if (eventRole == null)
|
||||
throw new Exception("Please provide correct role.");
|
||||
if (!eventRole.Event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
eventRole.Description = description;
|
||||
var s = _database.SaveChangesAsync();
|
||||
await ReplyAsync($"Updated event role `{eventRole.Id}` description to `{eventRole.Description}`");
|
||||
@@ -242,6 +253,8 @@ namespace EventBot.Modules
|
||||
{
|
||||
if (eventRole == null)
|
||||
throw new Exception("Please provide correct role.");
|
||||
if (!eventRole.Event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
eventRole.MaxParticipants = maxParticipants;
|
||||
var s = _database.SaveChangesAsync();
|
||||
await ReplyAsync($"Updated event role `{eventRole.Id}` maximum participant count to `{eventRole.MaxParticipants}`");
|
||||
@@ -258,7 +271,11 @@ namespace EventBot.Modules
|
||||
{
|
||||
if (eventRole == null)
|
||||
throw new Exception("Please provide correct role.");
|
||||
if (!_emotes.TryParse(emote, out IEmote parsedEmote))
|
||||
if (eventRole.Event.MessageId != 0)
|
||||
throw new Exception("Role emote can't be edited while event is open for registrasion.");
|
||||
if (!eventRole.Event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
if (!EmoteHelper.TryParse(emote, out IEmote parsedEmote))
|
||||
throw new ArgumentException("Invalid emote provided.");
|
||||
|
||||
if (eventRole.Event.Roles.Count(r => r.Emote == parsedEmote.ToString()) > 0)
|
||||
@@ -331,6 +348,8 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("No events were found for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
|
||||
await Context.Message.DeleteAsync();
|
||||
var message = await ReplyAsync(embed: _events.GenerateEventEmbed(@event).Build());
|
||||
@@ -343,7 +362,7 @@ namespace EventBot.Modules
|
||||
case Event.EventParticipactionType.Unspecified:
|
||||
throw new Exception("Event type was unspecified.");
|
||||
case Event.EventParticipactionType.Quick:
|
||||
await message.AddReactionsAsync(@event.Roles.OrderBy(e => e.SortNumber).Select(r => _emotes.Parse(r.Emote)).ToArray());
|
||||
await message.AddReactionsAsync(@event.Roles.OrderBy(e => e.SortNumber).Select(r => EmoteHelper.Parse(r.Emote)).ToArray());
|
||||
break;
|
||||
case Event.EventParticipactionType.Detailed:
|
||||
break;
|
||||
@@ -352,6 +371,83 @@ namespace EventBot.Modules
|
||||
}
|
||||
}
|
||||
|
||||
[Command("close")]
|
||||
[Summary("Closes event registration.")]
|
||||
public async Task EventClose(
|
||||
[Summary("Event to close")] Event @event = null)
|
||||
{
|
||||
if (@event == null)
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("No events were found for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
if (@event.MessageId == 0)
|
||||
throw new Exception("This event is already closed for registration.");
|
||||
|
||||
@event.MessageId = 0;
|
||||
@event.MessageChannelId = 0;
|
||||
await _database.SaveChangesAsync();
|
||||
await ReplyAsync($"Event `{@event.Id}` registration has been closed, it's registration message will now be normal message.");
|
||||
}
|
||||
|
||||
[Command("finalize")]
|
||||
[Summary("Archives event and reverts all role additions. This is irreversable.")]
|
||||
public async Task EventFinilize(
|
||||
[Summary("Event to finilize")] Event @event = null)
|
||||
{
|
||||
if (@event == null)
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("No events were found for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is already finalized.");
|
||||
|
||||
@event.Active = false;
|
||||
await _database.SaveChangesAsync();
|
||||
|
||||
await ReplyAsync($"Event `{@event.Id}` has been finilized. Removing participant roles...");
|
||||
if (@event.Guild.ParticipantRoleId != 0)
|
||||
foreach (var participant in @event.Participants)
|
||||
{
|
||||
var user = Context.Guild.GetUser(participant.UserId);
|
||||
await user.RemoveRoleAsync(Context.Guild.GetRole(@event.Guild.ParticipantRoleId));
|
||||
}
|
||||
await ReplyAsync($"Everyone's roles have been removed. I hope it was fun!");
|
||||
}
|
||||
|
||||
[Command("list")]
|
||||
[Summary("Lists all prevous events that took on this server.")]
|
||||
public async Task EventArchive()
|
||||
{
|
||||
var guildEvents = _database.Events.Where(e => e.GuildId == Context.Guild.Id).OrderBy(e => e.Opened).ToList();
|
||||
if (guildEvents.Count() == 0)
|
||||
throw new Exception("There are no events that roon on this server.");
|
||||
|
||||
var pagedEvents = guildEvents
|
||||
.Select((e, i) => new { Event = e, Index = i })
|
||||
.GroupBy(o => o.Index / 6)
|
||||
.Select(g => g.Select(o => o.Event));
|
||||
var pager = new PaginatedMessage()
|
||||
{
|
||||
Title = "List al all prevous events.",
|
||||
Color = Color.Blue,
|
||||
Options = new PaginatedAppearanceOptions()
|
||||
{
|
||||
Timeout = new TimeSpan(0, 3, 0),
|
||||
DisplayInformationIcon = false,
|
||||
JumpDisplayOptions = JumpDisplayOptions.Never
|
||||
}
|
||||
};
|
||||
pager.Pages = pagedEvents.Select(eg =>
|
||||
string.Join("\r\n", eg.Select(e =>
|
||||
$"`{e.Id}` **{e.Title}** {(e.Active ? "✅" : "❌")}\r\n" +
|
||||
$"Opened at {e.Opened.ToShortDateString()} {e.Opened.ToShortTimeString()}"
|
||||
))
|
||||
);
|
||||
await PagedReplyAsync(pager);
|
||||
}
|
||||
|
||||
[Command("participant add")]
|
||||
[Summary("Add user to event role. Acts like join command.")]
|
||||
public async Task EventParticipantAdd(
|
||||
@@ -367,12 +463,14 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null & !(int.TryParse(emoteOrId, out int roleId)))
|
||||
throw new Exception("Unable to locate any events for this guild.");
|
||||
else if (@event == null)
|
||||
else if (@event == null || roleId != 0)
|
||||
er = _database.EventRoles.FirstOrDefault(r => r.Id == roleId);
|
||||
else
|
||||
er = @event.Roles.FirstOrDefault(r => r.Emote == emoteOrId);
|
||||
if (er == null)
|
||||
throw new ArgumentException("Invalid emote or event id specified");
|
||||
if (!er.Event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
|
||||
await _events.TryJoinEvent(guildUser, er, extraInformation, false);
|
||||
await Context.Message.DeleteAsync(); // Protect somewhat sensitive data.
|
||||
@@ -388,6 +486,8 @@ namespace EventBot.Modules
|
||||
@event = _events.FindEventBy(Context.Guild);
|
||||
if (@event == null)
|
||||
throw new Exception("No events were found for this guild.");
|
||||
if (!@event.Active)
|
||||
throw new Exception("This event is finalized. Please make a new event.");
|
||||
|
||||
if (!(user is IGuildUser guildUser))
|
||||
throw new Exception("This command must be executed inside guild.");
|
||||
|
@@ -63,7 +63,6 @@ namespace EventBot
|
||||
return new SqliteDatabaseService(sp);
|
||||
})
|
||||
.AddSingleton<InteractiveService>()
|
||||
.AddSingleton<EmoteService>()
|
||||
//.AddSingleton<HttpClient>()
|
||||
//.AddSingleton<PictureService>()
|
||||
.BuildServiceProvider();
|
||||
|
@@ -36,6 +36,7 @@ namespace EventBot.Services
|
||||
_discord = services.GetRequiredService<DiscordSocketClient>();
|
||||
_discord.GuildAvailable += OnGuildAvaivable;
|
||||
}
|
||||
public DatabaseService(): base() {}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
|
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NeoSmart.Unicode;
|
||||
using System.Linq;
|
||||
using Discord;
|
||||
using DEmoji = Discord.Emoji;
|
||||
using UEmoji = NeoSmart.Unicode.Emoji;
|
||||
|
||||
namespace EventBot.Services
|
||||
{
|
||||
|
||||
public class EmoteService
|
||||
{
|
||||
private IEnumerable<string> emoji;
|
||||
|
||||
public EmoteService()
|
||||
{
|
||||
emoji = UEmoji.All.Select(e => e.Sequence.AsString);
|
||||
}
|
||||
|
||||
public bool TryParse(string input, out IEmote emote)
|
||||
{
|
||||
if(Emote.TryParse(input, out Emote parsedEmote))
|
||||
{
|
||||
emote = parsedEmote;
|
||||
return true;
|
||||
}
|
||||
if(emoji.Contains(input))
|
||||
{
|
||||
emote = new DEmoji(input);
|
||||
return true;
|
||||
}
|
||||
emote = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEmote Parse(string input)
|
||||
{
|
||||
if (!TryParse(input, out IEmote parsed))
|
||||
throw new ArgumentException("Failed to parse emote.");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -15,14 +15,12 @@ namespace EventBot.Services
|
||||
{
|
||||
private readonly DiscordSocketClient _discord;
|
||||
private readonly DatabaseService _database;
|
||||
private readonly EmoteService _emotes;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public EventManagementService(IServiceProvider services)
|
||||
{
|
||||
_discord = services.GetRequiredService<DiscordSocketClient>();
|
||||
_database = services.GetRequiredService<DatabaseService>();
|
||||
_emotes = services.GetRequiredService<EmoteService>();
|
||||
_services = services;
|
||||
|
||||
_discord.ReactionAdded += ReactionAddedAsync;
|
||||
@@ -128,7 +126,7 @@ namespace EventBot.Services
|
||||
var @event = _database.Events.FirstOrDefault(e => e.MessageId == message.Id);
|
||||
if (@event != null)
|
||||
{
|
||||
var role = @event.Roles.FirstOrDefault(r => reaction.Emote.Equals(_emotes.Parse(r.Emote)));
|
||||
var role = @event.Roles.FirstOrDefault(r => reaction.Emote.Equals(EmoteHelper.Parse(r.Emote)));
|
||||
if(role != null)
|
||||
{
|
||||
var userMessage = await message.GetOrDownloadAsync();
|
||||
|
@@ -9,6 +9,8 @@ namespace EventBot.Services
|
||||
{
|
||||
public MySqlDatabaseService(IServiceProvider services, DbContextOptions options) : base(services, options) { }
|
||||
public MySqlDatabaseService(IServiceProvider services) : base(services) { }
|
||||
public MySqlDatabaseService() : base() { }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
|
@@ -9,6 +9,7 @@ namespace EventBot.Services
|
||||
{
|
||||
public SqliteDatabaseService(IServiceProvider services, DbContextOptions options) : base(services, options) { }
|
||||
public SqliteDatabaseService(IServiceProvider services) : base(services) {}
|
||||
public SqliteDatabaseService() : base() { }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
|
6
README
Normal file
6
README
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
`set dbconnection="Server=localhost;Database=eventbot;User=root;Password=password;"`
|
||||
|
||||
|
||||
`Add-Migration InitialDatabase -Context MySqlDatabaseService -OutputDir Migrations\MySql`
|
||||
`Add-Migration InitialDatabase -Context SqliteDatabaseService -OutputDir Migrations\Sqlite`
|
Reference in New Issue
Block a user