.srkw, .srwl and .srbl commands added.

This commit is contained in:
Master Kwoth 2017-07-19 10:38:14 +02:00
parent 3f7f6cecbe
commit 4130317f40
16 changed files with 2240 additions and 76 deletions

View File

@ -0,0 +1,9 @@
namespace NadekoBot.Common.TypeReaders
{
public enum AddRemove
{
Add = 0,
Rem = 1,
Rm = 1,
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class streamrolekwblwl : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "Enabled",
table: "StreamRoleSettings",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "Keyword",
table: "StreamRoleSettings",
nullable: true);
migrationBuilder.CreateTable(
name: "StreamRoleBlacklistedUser",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
DateAdded = table.Column<DateTime>(nullable: true),
StreamRoleSettingsId = table.Column<int>(nullable: true),
UserId = table.Column<ulong>(nullable: false),
Username = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_StreamRoleBlacklistedUser", x => x.Id);
table.ForeignKey(
name: "FK_StreamRoleBlacklistedUser_StreamRoleSettings_StreamRoleSettingsId",
column: x => x.StreamRoleSettingsId,
principalTable: "StreamRoleSettings",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "StreamRoleWhitelistedUser",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
DateAdded = table.Column<DateTime>(nullable: true),
StreamRoleSettingsId = table.Column<int>(nullable: true),
UserId = table.Column<ulong>(nullable: false),
Username = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_StreamRoleWhitelistedUser", x => x.Id);
table.ForeignKey(
name: "FK_StreamRoleWhitelistedUser_StreamRoleSettings_StreamRoleSettingsId",
column: x => x.StreamRoleSettingsId,
principalTable: "StreamRoleSettings",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_StreamRoleBlacklistedUser_StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser",
column: "StreamRoleSettingsId");
migrationBuilder.CreateIndex(
name: "IX_StreamRoleWhitelistedUser_StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser",
column: "StreamRoleSettingsId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "StreamRoleBlacklistedUser");
migrationBuilder.DropTable(
name: "StreamRoleWhitelistedUser");
migrationBuilder.DropColumn(
name: "Enabled",
table: "StreamRoleSettings");
migrationBuilder.DropColumn(
name: "Keyword",
table: "StreamRoleSettings");
}
}
}

View File

@ -1126,6 +1126,26 @@ namespace NadekoBot.Migrations
b.ToTable("StartupCommand"); b.ToTable("StartupCommand");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime?>("DateAdded");
b.Property<int?>("StreamRoleSettingsId");
b.Property<ulong>("UserId");
b.Property<string>("Username");
b.HasKey("Id");
b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleBlacklistedUser");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -1135,10 +1155,14 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded"); b.Property<DateTime?>("DateAdded");
b.Property<bool>("Enabled");
b.Property<ulong>("FromRoleId"); b.Property<ulong>("FromRoleId");
b.Property<int>("GuildConfigId"); b.Property<int>("GuildConfigId");
b.Property<string>("Keyword");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
@ -1147,6 +1171,26 @@ namespace NadekoBot.Migrations
b.ToTable("StreamRoleSettings"); b.ToTable("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime?>("DateAdded");
b.Property<int?>("StreamRoleSettingsId");
b.Property<ulong>("UserId");
b.Property<string>("Username");
b.HasKey("Id");
b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleWhitelistedUser");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -1531,6 +1575,13 @@ namespace NadekoBot.Migrations
.HasForeignKey("BotConfigId"); .HasForeignKey("BotConfigId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.StreamRoleSettings")
.WithMany("Blacklist")
.HasForeignKey("StreamRoleSettingsId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
{ {
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig")
@ -1539,6 +1590,13 @@ namespace NadekoBot.Migrations
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b =>
{
b.HasOne("NadekoBot.Services.Database.Models.StreamRoleSettings")
.WithMany("Whitelist")
.HasForeignKey("StreamRoleSettingsId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
{ {
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")

View File

@ -2,24 +2,18 @@
using Discord.Commands; using Discord.Commands;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using System.Collections.Concurrent;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Common.Attributes; using NadekoBot.Common.Attributes;
using NadekoBot.Common.Collections; using NadekoBot.Common.Collections;
using NadekoBot.Modules.Games.Common.Trivia; using NadekoBot.Modules.Games.Common.Trivia;
using NadekoBot.Modules.Permissions.Services; using NadekoBot.Modules.Permissions.Services;
using NadekoBot.Common.TypeReaders;
namespace NadekoBot.Modules.Permissions namespace NadekoBot.Modules.Permissions
{ {
public partial class Permissions public partial class Permissions
{ {
public enum AddRemove
{
Add,
Rem
}
[Group] [Group]
public class BlacklistCommands : NadekoSubmodule public class BlacklistCommands : NadekoSubmodule
{ {

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Common.Exceptions
{
public class StreamRoleNotFoundException : Exception
{
public StreamRoleNotFoundException() : base("Stream role wasn't found.")
{
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Common.Exceptions
{
public class StreamRolePermissionException : Exception
{
public StreamRolePermissionException() : base("Stream role was unable to be applied.")
{
}
}
}

View File

@ -0,0 +1,8 @@
namespace NadekoBot.Modules.Utility.Common
{
public enum StreamRoleListType
{
Whitelist,
Blacklist,
}
}

View File

@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Database.Repositories;
namespace NadekoBot.Modules.Utility.Extensions
{
public static class StreamRoleExtensions
{
/// <summary>
/// Gets full stream role settings for the guild with the specified id.
/// </summary>
/// <param name="gc"></param>
/// <param name="guildId">Id of the guild to get stream role settings for.</param>
/// <returns></returns>
public static StreamRoleSettings GetStreamRoleSettings(this IGuildConfigRepository gc, ulong guildId)
{
var conf = gc.For(guildId, x => x.Include(y => y.StreamRole)
.Include(y => y.StreamRole.Whitelist)
.Include(y => y.StreamRole.Blacklist));
if (conf.StreamRole == null)
conf.StreamRole = new StreamRoleSettings();
return conf.StreamRole;
}
}
}

View File

@ -5,11 +5,15 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord; using Discord;
using Discord.WebSocket; using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using NLog; using NLog;
using NadekoBot.Modules.Utility.Extensions;
using NadekoBot.Common.TypeReaders;
using NadekoBot.Modules.Utility.Common;
using NadekoBot.Modules.Utility.Common.Exceptions;
using Discord.Net;
namespace NadekoBot.Modules.Utility.Services namespace NadekoBot.Modules.Utility.Services
{ {
@ -27,7 +31,7 @@ namespace NadekoBot.Modules.Utility.Services
this._log = LogManager.GetCurrentClassLogger(); this._log = LogManager.GetCurrentClassLogger();
guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole) guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole)
.Where(x => x.Value.FromRoleId != 0 && x.Value.AddRoleId != 0) .Where(x => x.Value != null && x.Value.Enabled)
.ToConcurrent(); .ToConcurrent();
client.GuildMemberUpdated += Client_GuildMemberUpdated; client.GuildMemberUpdated += Client_GuildMemberUpdated;
@ -38,51 +42,10 @@ namespace NadekoBot.Modules.Utility.Services
var _ = Task.Run(async () => var _ = Task.Run(async () =>
{ {
//if user wasn't streaming or didn't have a game status at all //if user wasn't streaming or didn't have a game status at all
// and has a game status now if ((!before.Game.HasValue || before.Game.Value.StreamType == StreamType.NotStreaming)
// and that status is a streaming status
// and we are supposed to give him a role
if ((!before.Game.HasValue || before.Game.Value.StreamType == StreamType.NotStreaming) &&
after.Game.HasValue &&
after.Game.Value.StreamType != StreamType.NotStreaming
&& guildSettings.TryGetValue(after.Guild.Id, out var setting)) && guildSettings.TryGetValue(after.Guild.Id, out var setting))
{ {
IRole fromRole; await TryApplyRole(after, setting).ConfigureAwait(false);
IRole addRole;
try
{
//get needed roles
fromRole = after.Guild.GetRole(setting.FromRoleId);
if (fromRole == null)
throw new InvalidOperationException();
addRole = after.Guild.GetRole(setting.AddRoleId);
if (addRole == null)
throw new InvalidOperationException();
}
catch (Exception ex)
{
StopStreamRole(before.Guild.Id);
_log.Warn("Error getting Stream Role(s). Disabling stream role feature.");
_log.Error(ex);
return;
}
try
{
//check if user is in the fromrole
if (after.Roles.Contains(fromRole))
{
//check if he doesn't have addrole already, to avoid errors
if(!after.Roles.Contains(addRole))
await after.AddRoleAsync(addRole).ConfigureAwait(false);
//schedule him for the role removal when he stops streaming
toRemove.TryAdd((addRole.Guild.Id, after.Id), addRole.Id);
}
}
catch (Exception ex)
{
_log.Warn("Failed adding stream role.");
_log.Error(ex);
}
} }
// try removing a role that was given to the user // try removing a role that was given to the user
@ -116,41 +79,204 @@ namespace NadekoBot.Modules.Utility.Services
return Task.CompletedTask; return Task.CompletedTask;
} }
public void SetStreamRole(IRole fromRole, IRole addRole) private async Task TryApplyRole(IGuildUser user, StreamRoleSettings setting)
{ {
// if the user has a game status now
// and that status is a streaming status
// and the feature is enabled
// and he's not blacklisted
// and keyword is either not set, or the game contains the keyword required, or he's whitelisted
if (user.Game.HasValue &&
user.Game.Value.StreamType != StreamType.NotStreaming
&& setting.Enabled
&& !setting.Blacklist.Any(x => x.UserId == user.Id)
&& (string.IsNullOrWhiteSpace(setting.Keyword)
|| user.Game.Value.Name.Contains(setting.Keyword)
|| setting.Whitelist.Any(x => x.UserId == user.Id)))
{
IRole fromRole;
IRole addRole;
//get needed roles
fromRole = user.Guild.GetRole(setting.FromRoleId);
if (fromRole == null)
throw new StreamRoleNotFoundException();
addRole = user.Guild.GetRole(setting.AddRoleId);
if (addRole == null)
throw new StreamRoleNotFoundException();
try
{
//check if user is in the fromrole
if (user.RoleIds.Contains(setting.FromRoleId))
{
//check if he doesn't have addrole already, to avoid errors
if (!user.RoleIds.Contains(setting.AddRoleId))
await user.AddRoleAsync(addRole).ConfigureAwait(false);
//schedule him for the role removal when he stops streaming
toRemove.TryAdd((addRole.Guild.Id, user.Id), addRole.Id);
}
}
catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden)
{
StopStreamRole(user.Guild.Id);
_log.Warn("Error adding stream role(s). Disabling stream role feature.");
_log.Error(ex);
throw new StreamRolePermissionException();
}
catch (Exception ex)
{
_log.Warn("Failed adding stream role.");
_log.Error(ex);
}
}
}
/// <summary>
/// Adds or removes a user from a blacklist or a whitelist in the specified guild.
/// </summary>
/// <param name="guildId">Id of the guild</param>
/// <param name="action">Add or rem action</param>
/// <param name="userId">User's Id</param>
/// <param name="userName">User's name#discrim</param>
/// <returns>Whether the operation was successful</returns>
public async Task<bool> ApplyListAction(StreamRoleListType listType, ulong guildId, AddRemove action, ulong userId, string userName)
{
userName.ThrowIfNull(nameof(userName));
bool success;
using (var uow = _db.UnitOfWork)
{
var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(guildId);
if (listType == StreamRoleListType.Whitelist)
{
var userObj = new StreamRoleWhitelistedUser()
{
UserId = userId,
Username = userName,
};
if (action == AddRemove.Rem)
success = streamRoleSettings.Whitelist.Remove(userObj);
else
success = streamRoleSettings.Whitelist.Add(userObj);
}
else
{
var userObj = new StreamRoleBlacklistedUser()
{
UserId = userId,
Username = userName,
};
if (action == AddRemove.Rem)
success = streamRoleSettings.Blacklist.Remove(userObj);
else
success = streamRoleSettings.Blacklist.Add(userObj);
}
await uow.CompleteAsync().ConfigureAwait(false);
}
return success;
}
/// <summary>
/// Sets keyword on a guild and updates the cache.
/// </summary>
/// <param name="guildId">Guild Id</param>
/// <param name="keyword">Keyword to set</param>
/// <returns>The keyword set</returns>
public string SetKeyword(ulong guildId, string keyword)
{
keyword = keyword?.Trim()?.ToLowerInvariant();
using (var uow = _db.UnitOfWork)
{
var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(guildId);
streamRoleSettings.Keyword = keyword;
UpdateCache(guildId, streamRoleSettings);
uow.Complete();
return streamRoleSettings.Keyword;
}
}
/// <summary>
/// Gets the currently set keyword on a guild.
/// </summary>
/// <param name="guildId">Guild Id</param>
/// <returns>The keyword set</returns>
public string GetKeyword(ulong guildId)
{
if (guildSettings.TryGetValue(guildId, out var outSetting))
return outSetting.Keyword;
StreamRoleSettings setting; StreamRoleSettings setting;
using (var uow = _db.UnitOfWork) using (var uow = _db.UnitOfWork)
{ {
var gc = uow.GuildConfigs.For(fromRole.Guild.Id, x => x.Include(y => y.StreamRole)); setting = uow.GuildConfigs.GetStreamRoleSettings(guildId);
}
if (gc.StreamRole == null) UpdateCache(guildId, setting);
gc.StreamRole = new StreamRoleSettings()
return setting.Keyword;
}
/// <summary>
/// Sets the role to monitor, and a role to which to add to
/// the user who starts streaming in the monitored role.
/// </summary>
/// <param name="fromRole">Role to monitor</param>
/// <param name="addRole">Role to add to the user</param>
public async Task SetStreamRole(IRole fromRole, IRole addRole)
{ {
AddRoleId = addRole.Id, fromRole.ThrowIfNull(nameof(fromRole));
FromRoleId = fromRole.Id addRole.ThrowIfNull(nameof(addRole));
};
else StreamRoleSettings setting;
using (var uow = _db.UnitOfWork)
{ {
gc.StreamRole.AddRoleId = addRole.Id; var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(fromRole.Guild.Id);
gc.StreamRole.FromRoleId = fromRole.Id;
} streamRoleSettings.Enabled = true;
setting = gc.StreamRole; streamRoleSettings.AddRoleId = addRole.Id;
uow.Complete(); streamRoleSettings.FromRoleId = fromRole.Id;
setting = streamRoleSettings;
await uow.CompleteAsync().ConfigureAwait(false);
} }
guildSettings.AddOrUpdate(fromRole.Guild.Id, (key) => setting, (key, old) => setting); UpdateCache(fromRole.Guild.Id, setting);
foreach (var usr in await fromRole.Guild.GetUsersAsync(CacheMode.CacheOnly).ConfigureAwait(false))
{
await TryApplyRole(usr, setting).ConfigureAwait(false);
await Task.Delay(500).ConfigureAwait(false);
}
} }
/// <summary>
/// Stops the stream role feature on the specified guild.
/// </summary>
/// <param name="guildId">Guild's Id</param>
public void StopStreamRole(ulong guildId) public void StopStreamRole(ulong guildId)
{ {
using (var uow = _db.UnitOfWork) using (var uow = _db.UnitOfWork)
{ {
var gc = uow.GuildConfigs.For(guildId, x => x.Include(y => y.StreamRole)); var streamRoleSettings = uow.GuildConfigs.GetStreamRoleSettings(guildId);
gc.StreamRole = null; streamRoleSettings.Enabled = false;
uow.Complete(); uow.Complete();
} }
guildSettings.TryRemove(guildId, out _); guildSettings.TryRemove(guildId, out _);
} }
private void UpdateCache(ulong guildId, StreamRoleSettings setting)
{
guildSettings.AddOrUpdate(guildId, (key) => setting, (key, old) => setting);
}
} }
} }

View File

@ -3,6 +3,8 @@ using Discord.Commands;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Common.Attributes; using NadekoBot.Common.Attributes;
using NadekoBot.Modules.Utility.Services; using NadekoBot.Modules.Utility.Services;
using NadekoBot.Common.TypeReaders;
using NadekoBot.Modules.Utility.Common;
namespace NadekoBot.Modules.Utility namespace NadekoBot.Modules.Utility
{ {
@ -16,7 +18,7 @@ namespace NadekoBot.Modules.Utility
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task StreamRole(IRole fromRole, IRole addRole) public async Task StreamRole(IRole fromRole, IRole addRole)
{ {
this._service.SetStreamRole(fromRole, addRole); await this._service.SetStreamRole(fromRole, addRole).ConfigureAwait(false);
await ReplyConfirmLocalized("stream_role_enabled", Format.Bold(fromRole.ToString()), Format.Bold(addRole.ToString())).ConfigureAwait(false); await ReplyConfirmLocalized("stream_role_enabled", Format.Bold(fromRole.ToString()), Format.Bold(addRole.ToString())).ConfigureAwait(false);
} }
@ -30,6 +32,62 @@ namespace NadekoBot.Modules.Utility
this._service.StopStreamRole(Context.Guild.Id); this._service.StopStreamRole(Context.Guild.Id);
await ReplyConfirmLocalized("stream_role_disabled").ConfigureAwait(false); await ReplyConfirmLocalized("stream_role_disabled").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases]
[RequireBotPermission(GuildPermission.ManageRoles)]
[RequireUserPermission(GuildPermission.ManageRoles)]
[RequireContext(ContextType.Guild)]
public async Task StreamRoleKeyword([Remainder]string keyword = null)
{
string kw = this._service.SetKeyword(Context.Guild.Id, keyword);
if(string.IsNullOrWhiteSpace(keyword))
await ReplyConfirmLocalized("stream_role_kw_reset").ConfigureAwait(false);
else
await ReplyConfirmLocalized("stream_role_kw_set", Format.Bold(kw)).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireBotPermission(GuildPermission.ManageRoles)]
[RequireUserPermission(GuildPermission.ManageRoles)]
[RequireContext(ContextType.Guild)]
public async Task StreamRoleBlacklist(AddRemove action, [Remainder] IGuildUser user)
{
var success = await this._service.ApplyListAction(StreamRoleListType.Blacklist, Context.Guild.Id, action, user.Id, user.ToString())
.ConfigureAwait(false);
if(action == AddRemove.Add)
if(success)
await ReplyConfirmLocalized("stream_role_bl_add", Format.Bold(user.ToString())).ConfigureAwait(false);
else
await ReplyConfirmLocalized("stream_role_bl_add_fail", Format.Bold(user.ToString())).ConfigureAwait(false);
else
if (success)
await ReplyConfirmLocalized("stream_role_bl_rem", Format.Bold(user.ToString())).ConfigureAwait(false);
else
await ReplyErrorLocalized("stream_role_bl_rem_fail", Format.Bold(user.ToString())).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireBotPermission(GuildPermission.ManageRoles)]
[RequireUserPermission(GuildPermission.ManageRoles)]
[RequireContext(ContextType.Guild)]
public async Task StreamRoleWhitelist(AddRemove action, [Remainder] IGuildUser user)
{
var success = await this._service.ApplyListAction(StreamRoleListType.Whitelist, Context.Guild.Id, action, user.Id, user.ToString())
.ConfigureAwait(false);
if (action == AddRemove.Add)
if(success)
await ReplyConfirmLocalized("stream_role_wl_add", Format.Bold(user.ToString())).ConfigureAwait(false);
else
await ReplyConfirmLocalized("stream_role_wl_add_fail", Format.Bold(user.ToString())).ConfigureAwait(false);
else
if (success)
await ReplyConfirmLocalized("stream_role_wl_rem", Format.Bold(user.ToString())).ConfigureAwait(false);
else
await ReplyErrorLocalized("stream_role_wl_rem_fail", Format.Bold(user.ToString())).ConfigureAwait(false);
}
} }
} }
} }

View File

@ -91,4 +91,8 @@
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" /> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" /> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Utility\Modules\" />
</ItemGroup>
</Project> </Project>

View File

@ -3546,4 +3546,31 @@
<data name="verboseerror_desc" xml:space="preserve"> <data name="verboseerror_desc" xml:space="preserve">
<value>Toggles whether the bot should print command errors when a command is incorrectly used.</value> <value>Toggles whether the bot should print command errors when a command is incorrectly used.</value>
</data> </data>
<data name="streamrolekeyword_cmd" xml:space="preserve">
<value>streamrolekw srkw</value>
</data>
<data name="streamrolekeyword_usage" xml:space="preserve">
<value>`{0}srkw` or `{0}srkw PUBG`</value>
</data>
<data name="streamrolekeyword_desc" xml:space="preserve">
<value>Sets keyword which is required in the stream's title in order for the streamrole to apply. Provide no keyword in order to reset.</value>
</data>
<data name="streamroleblacklist_cmd" xml:space="preserve">
<value>streamrolebl srbl</value>
</data>
<data name="streamroleblacklist_usage" xml:space="preserve">
<value>`{0}srbl add @b1nzy#1234` or `{0}srbl rem @b1nzy#1234`</value>
</data>
<data name="streamroleblacklist_desc" xml:space="preserve">
<value>Adds or removes a blacklisted user. Blacklisted users will never receive the stream role.</value>
</data>
<data name="streamrolewhitelist_cmd" xml:space="preserve">
<value>streamrolewl srwl</value>
</data>
<data name="streamrolewhitelist_usage" xml:space="preserve">
<value>`{0}srwl add @b1nzy#1234` or `{0}srwl rem @b1nzy#1234`</value>
</data>
<data name="streamrolewhitelist_desc" xml:space="preserve">
<value>Adds or removes a whitelisted user. Whitelisted users will receive the stream role even if they don't have the specified keyword in their stream title.</value>
</data>
</root> </root>

View File

@ -83,7 +83,7 @@ namespace NadekoBot.Services.Database.Models
public ulong? GameVoiceChannel { get; set; } = null; public ulong? GameVoiceChannel { get; set; } = null;
public bool VerboseErrors { get; set; } = false; public bool VerboseErrors { get; set; } = false;
public StreamRoleSettings StreamRole { get; set; } = new StreamRoleSettings(); public StreamRoleSettings StreamRole { get; set; }
//public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>(); //public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>();
} }

View File

@ -11,13 +11,77 @@ namespace NadekoBot.Services.Database.Models
public int GuildConfigId { get; set; } public int GuildConfigId { get; set; }
public GuildConfig GuildConfig { get; set; } public GuildConfig GuildConfig { get; set; }
/// <summary>
/// Whether the feature is enabled in the guild.
/// </summary>
public bool Enabled { get; set; }
/// <summary> /// <summary>
/// Id of the role to give to the users in the role 'FromRole' when they start streaming /// Id of the role to give to the users in the role 'FromRole' when they start streaming
/// </summary> /// </summary>
public ulong AddRoleId { get; set; } public ulong AddRoleId { get; set; }
/// <summary> /// <summary>
/// Id of the role whose users are eligible to get the 'AddRole' /// Id of the role whose users are eligible to get the 'AddRole'
/// </summary> /// </summary>
public ulong FromRoleId { get; set; } public ulong FromRoleId { get; set; }
/// <summary>
/// If set, feature will only apply to users who have this keyword in their streaming status.
/// </summary>
public string Keyword { get; set; }
/// <summary>
/// A collection of whitelisted users' IDs. Whitelisted users don't require 'keyword' in
/// order to get the stream role.
/// </summary>
public HashSet<StreamRoleWhitelistedUser> Whitelist { get; set; } = new HashSet<StreamRoleWhitelistedUser>();
/// <summary>
/// A collection of blacklisted users' IDs. Blacklisted useres will never get the stream role.
/// </summary>
public HashSet<StreamRoleBlacklistedUser> Blacklist { get; set; } = new HashSet<StreamRoleBlacklistedUser>();
}
public class StreamRoleBlacklistedUser : DbEntity
{
public ulong UserId { get; set; }
public string Username { get; set; }
public override bool Equals(object obj)
{
var x = obj as StreamRoleBlacklistedUser;
if (x == null)
return false;
return x.UserId == UserId;
}
public override int GetHashCode()
{
return UserId.GetHashCode();
}
}
public class StreamRoleWhitelistedUser : DbEntity
{
public ulong UserId { get; set; }
public string Username { get; set; }
public override bool Equals(object obj)
{
var x = obj as StreamRoleWhitelistedUser;
if (x == null)
return false;
return x.UserId == UserId;
}
public override int GetHashCode()
{
return UserId.GetHashCode();
}
} }
} }

View File

@ -610,6 +610,16 @@
"searches_yodify_error": "Failed to yodify your sentence.", "searches_yodify_error": "Failed to yodify your sentence.",
"utility_stream_role_enabled": "When a user from {0} role starts streaming, I will give them {1} role.", "utility_stream_role_enabled": "When a user from {0} role starts streaming, I will give them {1} role.",
"utility_stream_role_disabled": "Stream role feature has been disabled.", "utility_stream_role_disabled": "Stream role feature has been disabled.",
"utility_stream_role_kw_set": "Streamers now require {0} keyword in order to receive the role.",
"utility_stream_role_kw_reset": "Stream role keyword reset.",
"utility_stream_role_bl_add": "User {0} will never receive the stream role.",
"utility_stream_role_bl_add_fail": "User {0} is already blacklisted.",
"utility_stream_role_bl_rem": "User {0} is no longer blacklisted.",
"utility_stream_role_bl_rem_fail": "User {0} is not blacklisted.",
"utility_stream_role_wl_add": "User {0} will receive the stream role even if they don't have the keyword in the stream title.",
"utility_stream_role_wl_add_fail": "User {0} is already whitelisted.",
"utility_stream_role_wl_rem": "User {0} is no longer whitelisted.",
"utility_stream_role_wl_rem_fail": "User {0} is not whitelisted.",
"utiliity_joined": "Joined", "utiliity_joined": "Joined",
"utility_activity_line": "`{0}.` {1} [{2:F2}/s] - {3} total", "utility_activity_line": "`{0}.` {1} [{2:F2}/s] - {3} total",
"utility_activity_page": "Activity page #{0}", "utility_activity_page": "Activity page #{0}",