mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 09:18:27 -04:00
- Owner only attributes will now use fresh creds every time (no need for restart for owner only commands to start working once creds are changed)
- setgame/setstream use the new pubsub (also setstream will actually apply to all shards now) - setgame/setstream moved to SelfService - small cleanup
This commit is contained in:
@@ -6,8 +6,6 @@ using NadekoBot.Common;
|
|||||||
using NadekoBot.Services;
|
using NadekoBot.Services;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using StackExchange.Redis;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@@ -103,6 +101,7 @@ namespace NadekoBot
|
|||||||
|
|
||||||
var svcs = new ServiceCollection()
|
var svcs = new ServiceCollection()
|
||||||
.AddTransient<IBotCredentials>(_ => _creds) // bot creds
|
.AddTransient<IBotCredentials>(_ => _creds) // bot creds
|
||||||
|
.AddSingleton(_credsProvider)
|
||||||
.AddSingleton(_db) // database
|
.AddSingleton(_db) // database
|
||||||
.AddRedis(_creds.RedisOptions) // redis
|
.AddRedis(_creds.RedisOptions) // redis
|
||||||
.AddSingleton(Client) // discord socket client
|
.AddSingleton(Client) // discord socket client
|
||||||
@@ -282,7 +281,6 @@ namespace NadekoBot
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo cleanup
|
|
||||||
public async Task RunAsync()
|
public async Task RunAsync()
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
@@ -303,18 +301,13 @@ namespace NadekoBot
|
|||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
Log.Information("Shard {ShardId} connected in {Elapsed:F2}s", Client.ShardId, sw.Elapsed.TotalSeconds);
|
Log.Information("Shard {ShardId} connected in {Elapsed:F2}s", Client.ShardId, sw.Elapsed.TotalSeconds);
|
||||||
|
|
||||||
var stats = Services.GetRequiredService<IStatsService>();
|
|
||||||
stats.Initialize();
|
|
||||||
var commandHandler = Services.GetRequiredService<CommandHandler>();
|
var commandHandler = Services.GetRequiredService<CommandHandler>();
|
||||||
|
|
||||||
// start handling messages received in commandhandler
|
// start handling messages received in commandhandler
|
||||||
await commandHandler.StartHandling().ConfigureAwait(false);
|
await commandHandler.StartHandling().ConfigureAwait(false);
|
||||||
|
|
||||||
_ = await _commandService.AddModulesAsync(this.GetType().GetTypeInfo().Assembly, Services)
|
await _commandService.AddModulesAsync(typeof(Bot).Assembly, Services);
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
HandleStatusChanges();
|
|
||||||
IsReady = true;
|
IsReady = true;
|
||||||
_ = Task.Run(ExecuteReadySubscriptions);
|
_ = Task.Run(ExecuteReadySubscriptions);
|
||||||
Log.Information("Shard {ShardId} ready", Client.ShardId);
|
Log.Information("Shard {ShardId} ready", Client.ShardId);
|
||||||
@@ -356,53 +349,5 @@ namespace NadekoBot
|
|||||||
await RunAsync().ConfigureAwait(false);
|
await RunAsync().ConfigureAwait(false);
|
||||||
await Task.Delay(-1).ConfigureAwait(false);
|
await Task.Delay(-1).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// todo status changes don't belong here
|
|
||||||
private void HandleStatusChanges()
|
|
||||||
{
|
|
||||||
var sub = Services.GetService<IDataCache>().Redis.GetSubscriber();
|
|
||||||
sub.Subscribe(Client.CurrentUser.Id + "_status.game_set", async (ch, game) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var obj = new { Name = default(string), Activity = ActivityType.Playing };
|
|
||||||
obj = JsonConvert.DeserializeAnonymousType(game, obj);
|
|
||||||
await Client.SetGameAsync(obj.Name, type: obj.Activity).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warning(ex, "Error setting game");
|
|
||||||
}
|
|
||||||
}, CommandFlags.FireAndForget);
|
|
||||||
|
|
||||||
sub.Subscribe(Client.CurrentUser.Id + "_status.stream_set", async (ch, streamData) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var obj = new { Name = "", Url = "" };
|
|
||||||
obj = JsonConvert.DeserializeAnonymousType(streamData, obj);
|
|
||||||
await Client.SetGameAsync(obj.Name, obj.Url, ActivityType.Streaming).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warning(ex, "Error setting stream");
|
|
||||||
}
|
|
||||||
}, CommandFlags.FireAndForget);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task SetGameAsync(string game, ActivityType type)
|
|
||||||
{
|
|
||||||
var obj = new { Name = game, Activity = type };
|
|
||||||
var sub = Services.GetService<IDataCache>().Redis.GetSubscriber();
|
|
||||||
return sub.PublishAsync(Client.CurrentUser.Id + "_status.game_set", JsonConvert.SerializeObject(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task SetStreamAsync(string name, string link)
|
|
||||||
{
|
|
||||||
var obj = new { Name = name, Url = link };
|
|
||||||
var sub = Services.GetService<IDataCache>().Redis.GetSubscriber();
|
|
||||||
return sub.PublishAsync(Client.CurrentUser.Id + "_status.stream_set", JsonConvert.SerializeObject(obj));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,15 +3,17 @@ using System.Threading.Tasks;
|
|||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
using NadekoBot.Services;
|
||||||
|
|
||||||
namespace NadekoBot.Common.Attributes
|
namespace NadekoBot.Common.Attributes
|
||||||
{
|
{
|
||||||
|
// todo all getservice to getrequiredservice
|
||||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
||||||
public sealed class OwnerOnlyAttribute : PreconditionAttribute
|
public sealed class OwnerOnlyAttribute : PreconditionAttribute
|
||||||
{
|
{
|
||||||
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo executingCommand, IServiceProvider services)
|
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo executingCommand, IServiceProvider services)
|
||||||
{
|
{
|
||||||
var creds = services.GetService<IBotCredentials>();
|
var creds = services.GetRequiredService<BotCredsProvider>().GetCreds();
|
||||||
|
|
||||||
return Task.FromResult((creds.IsOwner(context.User) || context.Client.CurrentUser.Id == context.User.Id ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
|
return Task.FromResult((creds.IsOwner(context.User) || context.Client.CurrentUser.Id == context.User.Id ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
|
||||||
}
|
}
|
||||||
|
@@ -432,7 +432,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
.WithDefault(Context)
|
.WithDefault(Context)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
await _bot.SetGameAsync(game is null ? game : rep.Replace(game), type).ConfigureAwait(false);
|
await _service.SetGameAsync(game is null ? game : rep.Replace(game), type).ConfigureAwait(false);
|
||||||
|
|
||||||
await ReplyConfirmLocalizedAsync("set_game").ConfigureAwait(false);
|
await ReplyConfirmLocalizedAsync("set_game").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
{
|
{
|
||||||
name = name ?? "";
|
name = name ?? "";
|
||||||
|
|
||||||
await _client.SetGameAsync(name, url, ActivityType.Streaming).ConfigureAwait(false);
|
await _service.SetStreamAsync(name, url).ConfigureAwait(false);
|
||||||
|
|
||||||
await ReplyConfirmLocalizedAsync("set_stream").ConfigureAwait(false);
|
await ReplyConfirmLocalizedAsync("set_stream").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
{
|
{
|
||||||
private readonly Timer _t;
|
private readonly Timer _t;
|
||||||
private readonly BotConfigService _bss;
|
private readonly BotConfigService _bss;
|
||||||
|
private readonly SelfService _selfService;
|
||||||
private readonly Replacer _rep;
|
private readonly Replacer _rep;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly Bot _bot;
|
private readonly Bot _bot;
|
||||||
@@ -28,11 +29,12 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PlayingRotateService(DiscordSocketClient client, DbService db, Bot bot,
|
public PlayingRotateService(DiscordSocketClient client, DbService db, Bot bot,
|
||||||
BotConfigService bss, IEnumerable<IPlaceholderProvider> phProviders)
|
BotConfigService bss, IEnumerable<IPlaceholderProvider> phProviders, SelfService selfService)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_bot = bot;
|
_bot = bot;
|
||||||
_bss = bss;
|
_bss = bss;
|
||||||
|
_selfService = selfService;
|
||||||
|
|
||||||
if (client.ShardId == 0)
|
if (client.ShardId == 0)
|
||||||
{
|
{
|
||||||
@@ -70,7 +72,7 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
: rotatingStatuses[state.Index++];
|
: rotatingStatuses[state.Index++];
|
||||||
|
|
||||||
var statusText = _rep.Replace(playingStatus.Status);
|
var statusText = _rep.Replace(playingStatus.Status);
|
||||||
await _bot.SetGameAsync(statusText, playingStatus.Type);
|
await _selfService.SetGameAsync(statusText, playingStatus.Type);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@@ -14,6 +14,7 @@ using System.Threading;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using NadekoBot.Common;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Administration.Services
|
namespace NadekoBot.Modules.Administration.Services
|
||||||
@@ -38,10 +39,14 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
private readonly IImageCache _imgs;
|
private readonly IImageCache _imgs;
|
||||||
private readonly IHttpClientFactory _httpFactory;
|
private readonly IHttpClientFactory _httpFactory;
|
||||||
private readonly BotConfigService _bss;
|
private readonly BotConfigService _bss;
|
||||||
|
private readonly IPubSub _pubSub;
|
||||||
|
|
||||||
|
//keys
|
||||||
|
private readonly TypedKey<ActivityPubData> _activitySetKey;
|
||||||
|
|
||||||
public SelfService(DiscordSocketClient client, CommandHandler cmdHandler, DbService db,
|
public SelfService(DiscordSocketClient client, CommandHandler cmdHandler, DbService db,
|
||||||
IBotStrings strings, IBotCredentials creds, IDataCache cache, IHttpClientFactory factory,
|
IBotStrings strings, IBotCredentials creds, IDataCache cache, IHttpClientFactory factory,
|
||||||
BotConfigService bss)
|
BotConfigService bss, IPubSub pubSub)
|
||||||
{
|
{
|
||||||
_redis = cache.Redis;
|
_redis = cache.Redis;
|
||||||
_cmdHandler = cmdHandler;
|
_cmdHandler = cmdHandler;
|
||||||
@@ -53,7 +58,11 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
_imgs = cache.LocalImages;
|
_imgs = cache.LocalImages;
|
||||||
_httpFactory = factory;
|
_httpFactory = factory;
|
||||||
_bss = bss;
|
_bss = bss;
|
||||||
|
_pubSub = pubSub;
|
||||||
|
_activitySetKey = new("activity.set");
|
||||||
|
|
||||||
|
HandleStatusChanges();
|
||||||
|
|
||||||
var sub = _redis.GetSubscriber();
|
var sub = _redis.GetSubscriber();
|
||||||
if (_client.ShardId == 0)
|
if (_client.ShardId == 0)
|
||||||
{
|
{
|
||||||
@@ -384,5 +393,34 @@ namespace NadekoBot.Modules.Administration.Services
|
|||||||
_bss.ModifyConfig(config => { isToAll = config.ForwardToAllOwners = !config.ForwardToAllOwners; });
|
_bss.ModifyConfig(config => { isToAll = config.ForwardToAllOwners = !config.ForwardToAllOwners; });
|
||||||
return isToAll;
|
return isToAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo pubsub via IPubSub
|
||||||
|
private void HandleStatusChanges()
|
||||||
|
{
|
||||||
|
_pubSub.Sub(_activitySetKey, async data =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _client.SetGameAsync(data.Name, data.Link, type: data.Type);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warning(ex, "Error setting activity");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SetGameAsync(string game, ActivityType type)
|
||||||
|
=> _pubSub.Pub(_activitySetKey, new() {Name = game, Link = null, Type = type});
|
||||||
|
|
||||||
|
public Task SetStreamAsync(string name, string link)
|
||||||
|
=> _pubSub.Pub(_activitySetKey, new() { Name = name, Link = link, Type = ActivityType.Streaming });
|
||||||
|
|
||||||
|
private class ActivityPubData
|
||||||
|
{
|
||||||
|
public string Name { get; init; }
|
||||||
|
public string Link { get; init; }
|
||||||
|
public ActivityType Type { get; init; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -15,6 +15,5 @@ namespace NadekoBot.Services
|
|||||||
|
|
||||||
TimeSpan GetUptime();
|
TimeSpan GetUptime();
|
||||||
string GetUptimeString(string separator = ", ");
|
string GetUptimeString(string separator = ", ");
|
||||||
void Initialize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,17 +8,18 @@ using System.Linq;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NadekoBot.Common.ModuleBehaviors;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public class StatsService : IStatsService, INService
|
public class StatsService : IStatsService, IReadyExecutor, INService
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly DateTime _started;
|
private readonly DateTime _started;
|
||||||
|
|
||||||
public const string BotVersion = "3.0.0-alpha1";
|
public const string BotVersion = "3.0.0-beta1";
|
||||||
public string Author => "Kwoth#2452";
|
public string Author => "Kwoth#2452";
|
||||||
public string Library => "Discord.Net";
|
public string Library => "Discord.Net";
|
||||||
|
|
||||||
@@ -156,13 +157,6 @@ namespace NadekoBot.Services
|
|||||||
}, null, TimeSpan.FromMinutes(5), TimeSpan.FromHours(1));
|
}, null, TimeSpan.FromMinutes(5), TimeSpan.FromHours(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
var guilds = _client.Guilds.ToArray();
|
|
||||||
_textChannels = guilds.Sum(g => g.Channels.Count(cx => cx is ITextChannel));
|
|
||||||
_voiceChannels = guilds.Sum(g => g.Channels.Count(cx => cx is IVoiceChannel));
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSpan GetUptime() =>
|
public TimeSpan GetUptime() =>
|
||||||
DateTime.UtcNow - _started;
|
DateTime.UtcNow - _started;
|
||||||
|
|
||||||
@@ -171,5 +165,13 @@ namespace NadekoBot.Services
|
|||||||
var time = GetUptime();
|
var time = GetUptime();
|
||||||
return $"{time.Days} days{separator}{time.Hours} hours{separator}{time.Minutes} minutes";
|
return $"{time.Days} days{separator}{time.Hours} hours{separator}{time.Minutes} minutes";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task OnReadyAsync()
|
||||||
|
{
|
||||||
|
var guilds = _client.Guilds;
|
||||||
|
_textChannels = guilds.Sum(g => g.Channels.Count(cx => cx is ITextChannel));
|
||||||
|
_voiceChannels = guilds.Sum(g => g.Channels.Count(cx => cx is IVoiceChannel));
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user