.vcrole and .vcrolelist added

This commit is contained in:
Kwoth 2017-03-11 08:00:58 +01:00
parent defde0ce34
commit a541ad3414
10 changed files with 1649 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class vcrole : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "VcRoleInfo",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
DateAdded = table.Column<DateTime>(nullable: true),
GuildConfigId = table.Column<int>(nullable: true),
RoleId = table.Column<ulong>(nullable: false),
VoiceChannelId = table.Column<ulong>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_VcRoleInfo", x => x.Id);
table.ForeignKey(
name: "FK_VcRoleInfo_GuildConfigs_GuildConfigId",
column: x => x.GuildConfigId,
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_VcRoleInfo_GuildConfigId",
table: "VcRoleInfo",
column: "GuildConfigId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "VcRoleInfo");
}
}
}

View File

@ -963,6 +963,26 @@ namespace NadekoBot.Migrations
b.ToTable("PokeGame"); b.ToTable("PokeGame");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime?>("DateAdded");
b.Property<int?>("GuildConfigId");
b.Property<ulong>("RoleId");
b.Property<ulong>("VoiceChannelId");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("VcRoleInfo");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -1196,6 +1216,13 @@ namespace NadekoBot.Migrations
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
.WithMany("VcRoleInfos")
.HasForeignKey("GuildConfigId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
{ {
b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Affinity") b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Affinity")

View File

@ -0,0 +1,177 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using System.Threading.Tasks;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
namespace NadekoBot.Modules.Administration
{
public partial class Administration
{
[Group]
public class VcRoleCommands : NadekoSubmodule
{
private static ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, IRole>> vcRoles { get; }
static VcRoleCommands()
{
NadekoBot.Client.UserVoiceStateUpdated += ClientOnUserVoiceStateUpdated;
vcRoles = new ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, IRole>>();
foreach (var gconf in NadekoBot.AllGuildConfigs)
{
var g = NadekoBot.Client.GetGuild(gconf.GuildId);
if (g == null)
continue; //todo delete everything from db if guild doesn't exist?
var infos = new ConcurrentDictionary<ulong, IRole>();
vcRoles.TryAdd(gconf.GuildId, infos);
foreach (var ri in gconf.VcRoleInfos)
{
var role = g.GetRole(ri.RoleId);
if (role == null)
continue; //todo remove this entry from db
infos.TryAdd(ri.VoiceChannelId, role);
}
}
}
private static Task ClientOnUserVoiceStateUpdated(SocketUser usr, SocketVoiceState oldState,
SocketVoiceState newState)
{
var gusr = usr as SocketGuildUser;
if (gusr == null)
return Task.CompletedTask;
var oldVc = oldState.VoiceChannel;
var newVc = newState.VoiceChannel;
var _ = Task.Run(async () =>
{
try
{
if (oldVc != newVc)
{
ulong guildId;
guildId = newVc?.Guild.Id ?? oldVc.Guild.Id;
ConcurrentDictionary<ulong, IRole> guildVcRoles;
if (vcRoles.TryGetValue(guildId, out guildVcRoles))
{
IRole role;
//remove old
if (oldVc != null && guildVcRoles.TryGetValue(oldVc.Id, out role))
{
if (gusr.RoleIds.Contains(role.Id))
{
await gusr.RemoveRolesAsync(role).ConfigureAwait(false);
await Task.Delay(500).ConfigureAwait(false);
}
}
//add new
if (newVc != null && guildVcRoles.TryGetValue(newVc.Id, out role))
{
if (!gusr.RoleIds.Contains(role.Id))
await gusr.AddRolesAsync(role).ConfigureAwait(false);
}
}
}
}
catch (Exception ex)
{
Administration._log.Warn(ex);
}
});
return Task.CompletedTask;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireUserPermission(GuildPermission.ManageRoles)]
[RequireUserPermission(GuildPermission.ManageChannels)]
[RequireBotPermission(GuildPermission.ManageRoles)]
// todo wait for the fix [RequireBotPermission(GuildPermission.ManageChannels)]
[RequireContext(ContextType.Guild)]
public async Task VcRole([Remainder]IRole role = null)
{
var user = (IGuildUser) Context.User;
var vc = user.VoiceChannel;
if (vc == null || vc.GuildId != user.GuildId)
{
await ReplyErrorLocalized("must_be_in_voice").ConfigureAwait(false);
return;
}
var guildVcRoles = vcRoles.GetOrAdd(user.GuildId, new ConcurrentDictionary<ulong, IRole>());
if (role == null)
{
if (guildVcRoles.TryRemove(vc.Id, out role))
{
await ReplyConfirmLocalized("vcrole_removed", Format.Bold(vc.Name)).ConfigureAwait(false);
using (var uow = DbHandler.UnitOfWork())
{
var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.VcRoleInfos));
conf.VcRoleInfos.RemoveWhere(x => x.VoiceChannelId == vc.Id);
uow.Complete();
}
}
}
else
{
guildVcRoles.AddOrUpdate(vc.Id, role, (key, old) => role);
using (var uow = DbHandler.UnitOfWork())
{
var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.VcRoleInfos));
conf.VcRoleInfos.RemoveWhere(x => x.VoiceChannelId == vc.Id); // remove old one
conf.VcRoleInfos.Add(new VcRoleInfo()
{
VoiceChannelId = vc.Id,
RoleId = role.Id,
}); // add new one
uow.Complete();
}
await ReplyConfirmLocalized("vcrole_added", Format.Bold(vc.Name), Format.Bold(role.Name)).ConfigureAwait(false);
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task VcRoleList()
{
var guild = (SocketGuild) Context.Guild;
string text;
ConcurrentDictionary<ulong, IRole> roles;
if (vcRoles.TryGetValue(Context.Guild.Id, out roles))
{
if (!roles.Any())
{
text = GetText("no_vcroles");
}
else
{
text = string.Join("\n", roles.Select(x =>
$"{Format.Bold(guild.GetVoiceChannel(x.Key)?.Name ?? x.Key.ToString())} => {x.Value}"));
}
}
else
{
text = GetText("no_vcroles");
}
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle(GetText("vc_role_list"))
.WithDescription(text))
.ConfigureAwait(false);
}
}
}
}

View File

@ -8645,6 +8645,60 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to vcrole.
/// </summary>
public static string vcrole_cmd {
get {
return ResourceManager.GetString("vcrole_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sets or resets a role which will be given to users who join the voice channel you&apos;re in when you run this command. Provide no role name to disable. You must be in a voice channel to run this command..
/// </summary>
public static string vcrole_desc {
get {
return ResourceManager.GetString("vcrole_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}vcrole SomeRole` or `{0}vcrole`.
/// </summary>
public static string vcrole_usage {
get {
return ResourceManager.GetString("vcrole_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to vcrolelist.
/// </summary>
public static string vcrolelist_cmd {
get {
return ResourceManager.GetString("vcrolelist_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shows a list of currently set voice channel roles..
/// </summary>
public static string vcrolelist_desc {
get {
return ResourceManager.GetString("vcrolelist_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}vcrolelist`.
/// </summary>
public static string vcrolelist_usage {
get {
return ResourceManager.GetString("vcrolelist_usage", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to verbose v. /// Looks up a localized string similar to verbose v.
/// </summary> /// </summary>

View File

@ -3168,4 +3168,22 @@
<data name="lucky7_usage" xml:space="preserve"> <data name="lucky7_usage" xml:space="preserve">
<value>`{0}l7 10` or `{0}l7 move` or `{0}l7 s`</value> <value>`{0}l7 10` or `{0}l7 move` or `{0}l7 s`</value>
</data> </data>
<data name="vcrolelist_cmd" xml:space="preserve">
<value>vcrolelist</value>
</data>
<data name="vcrolelist_desc" xml:space="preserve">
<value>Shows a list of currently set voice channel roles.</value>
</data>
<data name="vcrolelist_usage" xml:space="preserve">
<value>`{0}vcrolelist`</value>
</data>
<data name="vcrole_cmd" xml:space="preserve">
<value>vcrole</value>
</data>
<data name="vcrole_desc" xml:space="preserve">
<value>Sets or resets a role which will be given to users who join the voice channel you're in when you run this command. Provide no role name to disable. You must be in a voice channel to run this command.</value>
</data>
<data name="vcrole_usage" xml:space="preserve">
<value>`{0}vcrole SomeRole` or `{0}vcrole`</value>
</data>
</root> </root>

View File

@ -763,6 +763,15 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to You must be in a voice channel on this server..
/// </summary>
public static string administration_must_be_in_voice {
get {
return ResourceManager.GetString("administration_must_be_in_voice", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to I don&apos;t have the permission necessary for that most likely.. /// Looks up a localized string similar to I don&apos;t have the permission necessary for that most likely..
/// </summary> /// </summary>
@ -862,6 +871,15 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to There are no voice channel roles..
/// </summary>
public static string administration_no_vcroles {
get {
return ResourceManager.GetString("administration_no_vcroles", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Old message. /// Looks up a localized string similar to Old message.
/// </summary> /// </summary>
@ -1657,6 +1675,33 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Voice channel roles.
/// </summary>
public static string administration_vc_role_list {
get {
return ResourceManager.GetString("administration_vc_role_list", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Users who join {0} voice channel will get {1} role..
/// </summary>
public static string administration_vcrole_added {
get {
return ResourceManager.GetString("administration_vcrole_added", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Users who join {0} voice channel will no longer get a role..
/// </summary>
public static string administration_vcrole_removed {
get {
return ResourceManager.GetString("administration_vcrole_removed", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Voice channel created. /// Looks up a localized string similar to Voice channel created.
/// </summary> /// </summary>

View File

@ -2230,7 +2230,22 @@ Owner ID: {2}</value>
<data name="gambling_page" xml:space="preserve"> <data name="gambling_page" xml:space="preserve">
<value>page {0}</value> <value>page {0}</value>
</data> </data>
<data name="administration_must_be_in_voice" xml:space="preserve">
<value>You must be in a voice channel on this server.</value>
</data>
<data name="administration_no_vcroles" xml:space="preserve">
<value>There are no voice channel roles.</value>
</data>
<data name="administration_user_muted_time" xml:space="preserve"> <data name="administration_user_muted_time" xml:space="preserve">
<value>{0} has been **muted** from text and voice chat for {1} minutes.</value> <value>{0} has been **muted** from text and voice chat for {1} minutes.</value>
</data> </data>
<data name="administration_vcrole_added" xml:space="preserve">
<value>Users who join {0} voice channel will get {1} role.</value>
</data>
<data name="administration_vcrole_removed" xml:space="preserve">
<value>Users who join {0} voice channel will no longer get a role.</value>
</data>
<data name="administration_vc_role_list" xml:space="preserve">
<value>Voice channel roles</value>
</data>
</root> </root>

View File

@ -70,10 +70,17 @@ namespace NadekoBot.Services.Database.Models
public string TimeZoneId { get; set; } = null; public string TimeZoneId { get; set; } = null;
public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new HashSet<UnmuteTimer>(); public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new HashSet<UnmuteTimer>();
public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
//public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>(); //public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>();
} }
public class VcRoleInfo : DbEntity
{
public ulong VoiceChannelId { get; set; }
public ulong RoleId { get; set; }
}
public class UnmuteTimer : DbEntity public class UnmuteTimer : DbEntity
{ {
public ulong UserId { get; set; } public ulong UserId { get; set; }

View File

@ -17,6 +17,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl
.ThenInclude(ls => ls.IgnoredChannels) .ThenInclude(ls => ls.IgnoredChannels)
.Include(gc => gc.MutedUsers) .Include(gc => gc.MutedUsers)
.Include(gc => gc.UnmuteTimers) .Include(gc => gc.UnmuteTimers)
.Include(gc => gc.VcRoleInfos)
.Include(gc => gc.GenerateCurrencyChannelIds) .Include(gc => gc.GenerateCurrencyChannelIds)
.Include(gc => gc.FilterInvitesChannelIds) .Include(gc => gc.FilterInvitesChannelIds)
.Include(gc => gc.FilterWordsChannelIds) .Include(gc => gc.FilterWordsChannelIds)