Added .streamrole, needs testing.
This commit is contained in:
parent
67f0cfb717
commit
b8573f11b5
1597
src/NadekoBot/Migrations/20170714021615_stream-role.Designer.cs
generated
Normal file
1597
src/NadekoBot/Migrations/20170714021615_stream-role.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
46
src/NadekoBot/Migrations/20170714021615_stream-role.cs
Normal file
46
src/NadekoBot/Migrations/20170714021615_stream-role.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class streamrole : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "StreamRoleSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
AddRoleId = table.Column<ulong>(nullable: false),
|
||||
DateAdded = table.Column<DateTime>(nullable: true),
|
||||
FromRoleId = table.Column<ulong>(nullable: false),
|
||||
GuildConfigId = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_StreamRoleSettings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_StreamRoleSettings_GuildConfigs_GuildConfigId",
|
||||
column: x => x.GuildConfigId,
|
||||
principalTable: "GuildConfigs",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_StreamRoleSettings_GuildConfigId",
|
||||
table: "StreamRoleSettings",
|
||||
column: "GuildConfigId",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "StreamRoleSettings");
|
||||
}
|
||||
}
|
||||
}
|
@ -1126,6 +1126,27 @@ namespace NadekoBot.Migrations
|
||||
b.ToTable("StartupCommand");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AddRoleId");
|
||||
|
||||
b.Property<DateTime?>("DateAdded");
|
||||
|
||||
b.Property<ulong>("FromRoleId");
|
||||
|
||||
b.Property<int>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("StreamRoleSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -1510,6 +1531,14 @@ namespace NadekoBot.Migrations
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig")
|
||||
.WithOne("StreamRole")
|
||||
.HasForeignKey("NadekoBot.Services.Database.Models.StreamRoleSettings", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
|
39
src/NadekoBot/Modules/Utility/Commands/StreamRoleCommands.cs
Normal file
39
src/NadekoBot/Modules/Utility/Commands/StreamRoleCommands.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Services.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Utility.Commands
|
||||
{
|
||||
public class StreamRoleCommands : NadekoSubmodule
|
||||
{
|
||||
private readonly StreamRoleService service;
|
||||
|
||||
public StreamRoleCommands(StreamRoleService service)
|
||||
{
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task StreamRole(IRole fromRole, IRole addRole)
|
||||
{
|
||||
this.service.SetStreamRole(fromRole, addRole);
|
||||
|
||||
await ReplyConfirmLocalized("stream_role_enabled", Format.Bold(fromRole.ToString()), Format.Bold(addRole.ToString())).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task StreamRole()
|
||||
{
|
||||
this.service.StopStreamRole(Context.Guild.Id);
|
||||
await ReplyConfirmLocalized("stream_role_disabled").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -91,6 +91,5 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Modules\Music\Classes\" />
|
||||
<Folder Include="Utility\Services\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1700,6 +1700,15 @@
|
||||
</data>
|
||||
<data name="save_usage" xml:space="preserve">
|
||||
<value>`{0}save classical1`</value>
|
||||
</data>
|
||||
<data name="streamrole_cmd" xml:space="preserve">
|
||||
<value>streamrole</value>
|
||||
</data>
|
||||
<data name="streamrole_desc" xml:space="preserve">
|
||||
<value>Sets a role which is monitored for streamers (FromRole), and a role to add if a user from 'FromRole' is streaming (AddRole). When a user from 'FromRole' starts streaming, they will receive an 'AddRole'. Provide no arguments to disable</value>
|
||||
</data>
|
||||
<data name="streamrole_usage" xml:space="preserve">
|
||||
<value>`{0}streamrole "Eligible Streamers" "Featured Streams"`</value>
|
||||
</data>
|
||||
<data name="load_cmd" xml:space="preserve">
|
||||
<value>load</value>
|
||||
|
@ -83,6 +83,8 @@ namespace NadekoBot.Services.Database.Models
|
||||
public ulong? GameVoiceChannel { get; set; } = null;
|
||||
public bool VerboseErrors { get; set; } = false;
|
||||
|
||||
public StreamRoleSettings StreamRole { get; set; } = new StreamRoleSettings();
|
||||
|
||||
//public List<ProtectionIgnoredChannel> ProtectionIgnoredChannels { get; set; } = new List<ProtectionIgnoredChannel>();
|
||||
}
|
||||
|
||||
|
23
src/NadekoBot/Services/Database/Models/StreamRoleSettings.cs
Normal file
23
src/NadekoBot/Services/Database/Models/StreamRoleSettings.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Database.Models
|
||||
{
|
||||
public class StreamRoleSettings : DbEntity
|
||||
{
|
||||
public int GuildConfigId { get; set; }
|
||||
public GuildConfig GuildConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id of the role to give to the users in the role 'FromRole' when they start streaming
|
||||
/// </summary>
|
||||
public ulong AddRoleId { get; set; }
|
||||
/// <summary>
|
||||
/// Id of the role whose users are eligible to get the 'AddRole'
|
||||
/// </summary>
|
||||
public ulong FromRoleId { get; set; }
|
||||
}
|
||||
}
|
@ -169,6 +169,12 @@ namespace NadekoBot.Services.Database
|
||||
|
||||
#endregion
|
||||
|
||||
#region streamrole
|
||||
modelBuilder.Entity<StreamRoleSettings>()
|
||||
.HasOne(x => x.GuildConfig)
|
||||
.WithOne(x => x.StreamRole);
|
||||
#endregion
|
||||
|
||||
#region BotConfig
|
||||
//var botConfigEntity = modelBuilder.Entity<BotConfig>();
|
||||
//botConfigEntity
|
||||
|
@ -45,6 +45,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
||||
.Include(gc => gc.AntiSpamSetting)
|
||||
.ThenInclude(x => x.IgnoredChannels)
|
||||
.Include(gc => gc.FollowedStreams)
|
||||
.Include(gc => gc.StreamRole)
|
||||
.ToList();
|
||||
|
||||
/// <summary>
|
||||
|
150
src/NadekoBot/Services/Utility/StreamRoleService.cs
Normal file
150
src/NadekoBot/Services/Utility/StreamRoleService.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using NadekoBot.Extensions;
|
||||
using Discord.WebSocket;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NLog;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class StreamRoleService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
private readonly ConcurrentDictionary<ulong, StreamRoleSettings> guildSettings;
|
||||
//(guildId, userId), roleId
|
||||
private readonly ConcurrentDictionary<(ulong GuildId, ulong UserId), ulong> toRemove = new ConcurrentDictionary<(ulong GuildId, ulong UserId), ulong>();
|
||||
private readonly Logger _log;
|
||||
|
||||
public StreamRoleService(DiscordSocketClient client, DbService db, IEnumerable<GuildConfig> gcs)
|
||||
{
|
||||
this._db = db;
|
||||
this._log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole)
|
||||
.ToConcurrent();
|
||||
|
||||
client.GuildMemberUpdated += Client_GuildMemberUpdated;
|
||||
}
|
||||
|
||||
private Task Client_GuildMemberUpdated(SocketGuildUser before, SocketGuildUser after)
|
||||
{
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
//if user wasn't streaming or didn't have a game status at all
|
||||
// and has a game status now
|
||||
// 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))
|
||||
{
|
||||
IRole fromRole;
|
||||
IRole addRole;
|
||||
try
|
||||
{
|
||||
//get needed roles
|
||||
fromRole = after.Guild.GetRole(setting.FromRoleId);
|
||||
addRole = after.Guild.GetRole(setting.AddRoleId);
|
||||
}
|
||||
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
|
||||
// if user had a game status
|
||||
// and he was streaming
|
||||
// and he no longer has a game status, or has a game status which is not a stream
|
||||
// and if he's scheduled for role removal, get the roleid to remove
|
||||
else if (before.Game.HasValue &&
|
||||
before.Game.Value.StreamType != StreamType.NotStreaming &&
|
||||
(!after.Game.HasValue || after.Game.Value.StreamType == StreamType.NotStreaming) &&
|
||||
toRemove.TryRemove((after.Guild.Id, after.Id), out var roleId))
|
||||
{
|
||||
try
|
||||
{
|
||||
//get the role to remove from the role id
|
||||
var role = after.Guild.GetRole(roleId);
|
||||
if (role == null)
|
||||
return;
|
||||
//check if user has the role which needs to be removed to avoid errors
|
||||
if (after.Roles.Contains(role))
|
||||
await after.RemoveRoleAsync(role).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Warn("Failed removing the stream role from the user who stopped streaming.");
|
||||
_log.Error(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void SetStreamRole(IRole fromRole, IRole addRole)
|
||||
{
|
||||
StreamRoleSettings setting;
|
||||
using (var uow = _db.UnitOfWork)
|
||||
{
|
||||
var gc = uow.GuildConfigs.For(fromRole.Guild.Id, x => x.Include(y => y.StreamRole));
|
||||
|
||||
if (gc.StreamRole == null)
|
||||
gc.StreamRole = new StreamRoleSettings()
|
||||
{
|
||||
AddRoleId = addRole.Id,
|
||||
FromRoleId = fromRole.Id
|
||||
};
|
||||
else
|
||||
{
|
||||
gc.StreamRole.AddRoleId = addRole.Id;
|
||||
gc.StreamRole.FromRoleId = fromRole.Id;
|
||||
}
|
||||
setting = gc.StreamRole;
|
||||
uow.Complete();
|
||||
}
|
||||
|
||||
guildSettings.AddOrUpdate(fromRole.Guild.Id, (key) => setting, (key, old) => setting);
|
||||
}
|
||||
|
||||
public void StopStreamRole(ulong guildId)
|
||||
{
|
||||
using (var uow = _db.UnitOfWork)
|
||||
{
|
||||
var gc = uow.GuildConfigs.For(guildId, x => x.Include(y => y.StreamRole));
|
||||
gc.StreamRole = null;
|
||||
uow.Complete();
|
||||
}
|
||||
|
||||
guildSettings.TryRemove(guildId, out _);
|
||||
}
|
||||
}
|
||||
}
|
@ -608,6 +608,8 @@
|
||||
"searches_wind_speed": "Wind speed",
|
||||
"searches_x_most_banned_champs": "The {0} most banned champions",
|
||||
"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_disabled": "Stream role feature has been disabled.",
|
||||
"utiliity_joined": "Joined",
|
||||
"utility_activity_line": "`{0}.` {1} [{2:F2}/s] - {3} total",
|
||||
"utility_activity_page": "Activity page #{0}",
|
||||
|
Loading…
Reference in New Issue
Block a user