Removed a bunch of obsolete alises, command strings and commands

This commit is contained in:
Kwoth
2024-04-26 01:01:09 +00:00
parent 6bc8e4b7d2
commit eca4a14cb6
27 changed files with 17 additions and 911 deletions

View File

@@ -42,6 +42,11 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- `.feed` should now correctly accept (and show) the message which can be passed as the third parameter
### Removed
- `.poll` commands removed, discord added polls.
- `.scpl` and other music soundcloud commands have been removed as soundcloud isn't issuing new api tokens for years now
## [4.3.22] - 23.04.2023
### Added

View File

@@ -9,7 +9,6 @@ public class OldCreds
public string GoogleApiKey { get; set; } = string.Empty;
public string MashapeKey { get; set; } = string.Empty;
public string OsuApiKey { get; set; } = string.Empty;
public string SoundCloudClientId { get; set; } = string.Empty;
public string CleverbotApiKey { get; set; } = string.Empty;
public string CarbonKey { get; set; } = string.Empty;
public int TotalShards { get; set; } = 1;

View File

@@ -1,14 +0,0 @@
#nullable disable
namespace Nadeko.Bot.Db.Models;
public class NsfwBlacklistedTag : DbEntity
{
public ulong GuildId { get; set; }
public string Tag { get; set; }
public override int GetHashCode()
=> Tag.GetHashCode(StringComparison.InvariantCulture);
public override bool Equals(object obj)
=> obj is NsfwBlacklistedTag x && x.Tag == Tag;
}

View File

@@ -15,5 +15,4 @@ public enum MusicType
Radio,
YouTube,
Local,
Soundcloud
}

View File

@@ -1,17 +0,0 @@
#nullable disable
namespace Nadeko.Bot.Db.Models;
public class Poll : DbEntity
{
public ulong GuildId { get; set; }
public ulong ChannelId { get; set; }
public string Question { get; set; }
public IndexedCollection<PollAnswer> Answers { get; set; }
public HashSet<PollVote> Votes { get; set; } = new();
}
public class PollAnswer : DbEntity, IIndexed
{
public int Index { get; set; }
public string Text { get; set; }
}

View File

@@ -1,14 +0,0 @@
#nullable disable
namespace Nadeko.Bot.Db.Models;
public class PollVote : DbEntity
{
public ulong UserId { get; set; }
public int VoteIndex { get; set; }
public override int GetHashCode()
=> UserId.GetHashCode();
public override bool Equals(object obj)
=> obj is PollVote p ? p.UserId == UserId : false;
}

View File

@@ -248,7 +248,7 @@ public partial class Administration : NadekoModule<AdministrationService>
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageChannels)]
[BotPerm(GuildPerm.ManageChannels)]
public async Task NsfwToggle()
public async Task AgeRestrictToggle()
{
var channel = (ITextChannel)ctx.Channel;
var isEnabled = channel.IsNsfw;

View File

@@ -40,111 +40,9 @@ public partial class Games : NadekoModule<GamesService>
var res = _service.GetEightballResponse(ctx.User.Id, question);
await ctx.Channel.EmbedAsync(_eb.Create()
.WithOkColor()
.WithDescription(ctx.User.ToString())
.AddField("❓ " + GetText(strs.question), question)
.AddField("🎱 " + GetText(strs._8ball), res));
.WithOkColor()
.WithDescription(ctx.User.ToString())
.AddField("❓ " + GetText(strs.question), question)
.AddField("🎱 " + GetText(strs._8ball), res));
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task RateGirl([Leftover] IGuildUser usr)
{
var gr = _service.GirlRatings.GetOrAdd(usr.Id, GetGirl);
var originalStream = await gr.Stream;
if (originalStream is null)
{
await ReplyErrorLocalizedAsync(strs.something_went_wrong);
return;
}
await using var imgStream = new MemoryStream();
lock (gr)
{
originalStream.Position = 0;
originalStream.CopyTo(imgStream);
}
imgStream.Position = 0;
await ctx.Channel.SendFileAsync(imgStream,
$"rating.png",
Format.Bold($"{ctx.User.Mention} Girl Rating For {usr}"),
embed: _eb.Create()
.WithOkColor()
.AddField("Hot", gr.Hot.ToString("F2"), true)
.AddField("Crazy", gr.Crazy.ToString("F2"), true)
.AddField("Advice", gr.Advice)
.WithImageUrl($"attachment://rating.png")
.Build());
}
private double NextDouble(double x, double y)
=> (_rng.NextDouble() * (y - x)) + x;
private GirlRating GetGirl(ulong uid)
{
var rng = new NadekoRandom();
var roll = rng.Next(1, 1001);
var ratings = _service.Ratings.GetAwaiter().GetResult();
double hot;
double crazy;
string advice;
if (roll < 500)
{
hot = NextDouble(0, 5);
crazy = NextDouble(4, 10);
advice = ratings.Nog;
}
else if (roll < 750)
{
hot = NextDouble(5, 8);
crazy = NextDouble(4, (.6 * hot) + 4);
advice = ratings.Fun;
}
else if (roll < 900)
{
hot = NextDouble(5, 10);
crazy = NextDouble((.61 * hot) + 4, 10);
advice = ratings.Dan;
}
else if (roll < 951)
{
hot = NextDouble(8, 10);
crazy = NextDouble(7, (.6 * hot) + 4);
advice = ratings.Dat;
}
else if (roll < 990)
{
hot = NextDouble(8, 10);
crazy = NextDouble(5, 7);
advice = ratings.Wif;
}
else if (roll < 999)
{
hot = NextDouble(8, 10);
crazy = NextDouble(2, 3.99d);
advice = ratings.Tra;
}
else
{
hot = NextDouble(8, 10);
crazy = NextDouble(4, 5);
advice = ratings.Uni;
}
return new(_images, crazy, hot, roll, advice);
}
[Cmd]
public async Task Linux(string guhnoo, string loonix)
=> await SendConfirmAsync(
$@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.
Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project.
There really is a {loonix}, and these people are using it, but it is just a part of the system they use. {loonix} is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. {loonix} is normally used in combination with the {guhnoo} operating system: the whole system is basically {guhnoo} with {loonix} added, or {guhnoo}/{loonix}. All the so-called {loonix} distributions are really distributions of {guhnoo}/{loonix}.");
}

View File

@@ -1,102 +0,0 @@
#nullable disable
using NadekoBot.Modules.Games.Services;
using Nadeko.Bot.Db.Models;
using System.Text;
namespace NadekoBot.Modules.Games;
public partial class Games
{
[Group]
public partial class PollCommands : NadekoModule<PollService>
{
private readonly DiscordSocketClient _client;
public PollCommands(DiscordSocketClient client)
=> _client = client;
[Cmd]
[UserPerm(GuildPerm.ManageMessages)]
[RequireContext(ContextType.Guild)]
public async Task Poll([Leftover] string arg)
{
if (string.IsNullOrWhiteSpace(arg))
return;
var poll = _service.CreatePoll(ctx.Guild.Id, ctx.Channel.Id, arg);
if (poll is null)
{
await ReplyErrorLocalizedAsync(strs.poll_invalid_input);
return;
}
if (_service.StartPoll(poll))
{
await ctx.Channel.EmbedAsync(_eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.poll_created(ctx.User.ToString())))
.WithDescription(Format.Bold(poll.Question)
+ "\n\n"
+ string.Join("\n",
poll.Answers.Select(x
=> $"`{x.Index + 1}.` {Format.Bold(x.Text)}"))));
}
else
await ReplyErrorLocalizedAsync(strs.poll_already_running);
}
[Cmd]
[UserPerm(GuildPerm.ManageMessages)]
[RequireContext(ContextType.Guild)]
public async Task PollStats()
{
if (!_service.ActivePolls.TryGetValue(ctx.Guild.Id, out var pr))
return;
await ctx.Channel.EmbedAsync(GetStats(pr.Poll, GetText(strs.current_poll_results)));
}
[Cmd]
[UserPerm(GuildPerm.ManageMessages)]
[RequireContext(ContextType.Guild)]
public async Task Pollend()
{
Poll p;
if ((p = _service.StopPoll(ctx.Guild.Id)) is null)
return;
var embed = GetStats(p, GetText(strs.poll_closed));
await ctx.Channel.EmbedAsync(embed);
}
public IEmbedBuilder GetStats(Poll poll, string title)
{
var results = poll.Votes.GroupBy(kvp => kvp.VoteIndex).ToDictionary(x => x.Key, x => x.Sum(_ => 1));
var totalVotesCast = results.Sum(x => x.Value);
var eb = _eb.Create().WithTitle(title);
var sb = new StringBuilder().AppendLine(Format.Bold(poll.Question)).AppendLine();
var stats = poll.Answers.Select(x =>
{
results.TryGetValue(x.Index, out var votes);
return (x.Index, votes, x.Text);
})
.OrderByDescending(x => x.votes)
.ToArray();
for (var i = 0; i < stats.Length; i++)
{
var (index, votes, text) = stats[i];
sb.AppendLine(GetText(strs.poll_result(index + 1, Format.Bold(text), Format.Bold(votes.ToString()))));
}
return eb.WithDescription(sb.ToString())
.WithFooter(GetText(strs.x_votes_cast(totalVotesCast)))
.WithOkColor();
}
}
}

View File

@@ -1,36 +0,0 @@
#nullable disable
using Microsoft.EntityFrameworkCore;
using Nadeko.Bot.Db.Models;
namespace NadekoBot.Db;
public static class PollExtensions
{
public static IEnumerable<Poll> GetAllPolls(this DbSet<Poll> polls)
=> polls.Include(x => x.Answers)
.Include(x => x.Votes)
.ToArray();
public static void RemovePoll(this DbContext ctx, int id)
{
var p = ctx.Set<Poll>().Include(x => x.Answers).Include(x => x.Votes).FirstOrDefault(x => x.Id == id);
if (p is null)
return;
if (p.Votes is not null)
{
ctx.RemoveRange(p.Votes);
p.Votes.Clear();
}
if (p.Answers is not null)
{
ctx.RemoveRange(p.Answers);
p.Answers.Clear();
}
ctx.Set<Poll>().Remove(p);
}
}

View File

@@ -1,63 +0,0 @@
#nullable disable
using Nadeko.Bot.Db.Models;
namespace NadekoBot.Modules.Games.Common;
public class PollRunner
{
public event Func<IUserMessage, IGuildUser, Task> OnVoted;
public Poll Poll { get; }
private readonly DbService _db;
private readonly SemaphoreSlim _locker = new(1, 1);
public PollRunner(DbService db, Poll poll)
{
_db = db;
Poll = poll;
}
public async Task<bool> TryVote(IUserMessage msg)
{
PollVote voteObj;
await _locker.WaitAsync();
try
{
// has to be a user message
// channel must be the same the poll started in
if (msg is null || msg.Author.IsBot || msg.Channel.Id != Poll.ChannelId)
return false;
// has to be an integer
if (!int.TryParse(msg.Content, out var vote))
return false;
--vote;
if (vote < 0 || vote >= Poll.Answers.Count)
return false;
var usr = msg.Author as IGuildUser;
if (usr is null)
return false;
voteObj = new()
{
UserId = msg.Author.Id,
VoteIndex = vote
};
if (!Poll.Votes.Add(voteObj))
return false;
_ = OnVoted?.Invoke(msg, usr);
}
finally { _locker.Release(); }
await using var uow = _db.GetDbContext();
var trackedPoll = uow.Set<Poll>().FirstOrDefault(x => x.Id == Poll.Id);
trackedPoll.Votes.Add(voteObj);
uow.SaveChanges();
return true;
}
public void End()
=> OnVoted = null;
}

View File

@@ -1,140 +0,0 @@
#nullable disable
using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Db;
using NadekoBot.Modules.Games.Common;
using Nadeko.Bot.Db.Models;
namespace NadekoBot.Modules.Games.Services;
public class PollService : IExecOnMessage
{
public ConcurrentDictionary<ulong, PollRunner> ActivePolls { get; } = new();
public int Priority
=> 5;
private readonly DbService _db;
private readonly IBotStrings _strs;
private readonly IEmbedBuilderService _eb;
public PollService(DbService db, IBotStrings strs, IEmbedBuilderService eb)
{
_db = db;
_strs = strs;
_eb = eb;
using var uow = db.GetDbContext();
ActivePolls = uow.Set<Poll>().GetAllPolls()
.ToDictionary(x => x.GuildId,
x =>
{
var pr = new PollRunner(db, x);
pr.OnVoted += Pr_OnVoted;
return pr;
})
.ToConcurrent();
}
public Poll CreatePoll(ulong guildId, ulong channelId, string input)
{
if (string.IsNullOrWhiteSpace(input) || !input.Contains(";"))
return null;
var data = input.Split(';');
if (data.Length < 3)
return null;
var col = new IndexedCollection<PollAnswer>(data.Skip(1)
.Select(x => new PollAnswer
{
Text = x
}));
return new()
{
Answers = col,
Question = data[0],
ChannelId = channelId,
GuildId = guildId,
Votes = new()
};
}
public bool StartPoll(Poll p)
{
var pr = new PollRunner(_db, p);
if (ActivePolls.TryAdd(p.GuildId, pr))
{
using (var uow = _db.GetDbContext())
{
uow.Set<Poll>().Add(p);
uow.SaveChanges();
}
pr.OnVoted += Pr_OnVoted;
return true;
}
return false;
}
public Poll StopPoll(ulong guildId)
{
if (ActivePolls.TryRemove(guildId, out var pr))
{
pr.OnVoted -= Pr_OnVoted;
using var uow = _db.GetDbContext();
uow.RemovePoll(pr.Poll.Id);
uow.SaveChanges();
return pr.Poll;
}
return null;
}
private async Task Pr_OnVoted(IUserMessage msg, IGuildUser usr)
{
var toDelete = await msg.Channel.SendConfirmAsync(_eb,
_strs.GetText(strs.poll_voted(Format.Bold(usr.ToString())), usr.GuildId));
toDelete.DeleteAfter(5);
try
{
await msg.DeleteAsync();
}
catch
{
}
}
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage msg)
{
if (guild is null)
return false;
if (!ActivePolls.TryGetValue(guild.Id, out var poll))
return false;
try
{
var voted = await poll.TryVote(msg);
if (voted)
{
Log.Information("User {UserName} [{UserId}] voted in a poll on {GuildName} [{GuildId}] server",
msg.Author.ToString(),
msg.Author.Id,
guild.Name,
guild.Id);
}
return voted;
}
catch (Exception ex)
{
Log.Warning(ex, "Error voting");
}
return false;
}
}

View File

@@ -589,36 +589,6 @@ public sealed partial class Music : NadekoModule<IMusicService>
await ctx.Channel.EmbedAsync(embed);
}
[Cmd]
[RequireContext(ContextType.Guild)]
public Task SoundCloudQueue([Leftover] string query)
=> QueueByQuery(query, false, MusicPlatform.SoundCloud);
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task SoundCloudPl([Leftover] string playlist)
{
if (string.IsNullOrWhiteSpace(playlist))
return;
var succ = await QueuePreconditionInternalAsync();
if (!succ)
return;
var mp = await _service.GetOrCreateMusicPlayerAsync((ITextChannel)ctx.Channel);
if (mp is null)
{
await ReplyErrorLocalizedAsync(strs.no_player);
return;
}
_ = ctx.Channel.TriggerTypingAsync();
await _service.EnqueueSoundcloudPlaylistAsync(mp, playlist, ctx.User.ToString());
await ctx.OkAsync();
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task Playlist([Leftover] string playlistQuery)

View File

@@ -22,7 +22,6 @@ public interface IMusicService : IPlaceholderProvider
bool TryGetMusicPlayer(ulong guildId, [MaybeNullWhen(false)] out IMusicPlayer musicPlayer);
Task<int> EnqueueYoutubePlaylistAsync(IMusicPlayer mp, string playlistId, string queuer);
Task EnqueueDirectoryAsync(IMusicPlayer mp, string dirPath, string queuer);
Task<int> EnqueueSoundcloudPlaylistAsync(IMusicPlayer mp, string playlist, string queuer);
Task<IUserMessage?> SendToOutputAsync(ulong guildId, IEmbedBuilder embed);
Task<bool> PlayAsync(ulong guildId, ulong voiceChannelId);
Task<IList<(string Title, string Url)>> SearchVideosAsync(string query);

View File

@@ -11,7 +11,6 @@ public sealed class MusicService : IMusicService
private readonly DbService _db;
private readonly IYoutubeResolver _ytResolver;
private readonly ILocalTrackResolver _localResolver;
private readonly ISoundcloudResolver _scResolver;
private readonly DiscordSocketClient _client;
private readonly IBotStrings _strings;
private readonly IGoogleApiService _googleApiService;
@@ -28,7 +27,6 @@ public sealed class MusicService : IMusicService
DbService db,
IYoutubeResolver ytResolver,
ILocalTrackResolver localResolver,
ISoundcloudResolver scResolver,
DiscordSocketClient client,
IBotStrings strings,
IGoogleApiService googleApiService,
@@ -40,7 +38,6 @@ public sealed class MusicService : IMusicService
_db = db;
_ytResolver = ytResolver;
_localResolver = localResolver;
_scResolver = scResolver;
_client = client;
_strings = strings;
_googleApiService = googleApiService;
@@ -120,21 +117,6 @@ public sealed class MusicService : IMusicService
}
}
public async Task<int> EnqueueSoundcloudPlaylistAsync(IMusicPlayer mp, string playlist, string queuer)
{
var i = 0;
await foreach (var track in _scResolver.ResolvePlaylistAsync(playlist))
{
if (mp.IsKilled)
break;
mp.EnqueueTrack(track, queuer);
++i;
}
return i;
}
private async Task<IMusicPlayer?> CreateMusicPlayerInternalAsync(ulong guildId, ITextChannel defaultChannel)
{
var queue = new MusicQueue();

View File

@@ -1,78 +0,0 @@
#nullable disable
using Newtonsoft.Json;
namespace NadekoBot.Services;
public class SoundCloudApiService : INService
{
private readonly IHttpClientFactory _httpFactory;
public SoundCloudApiService(IHttpClientFactory factory)
=> _httpFactory = factory;
public async Task<SoundCloudVideo> ResolveVideoAsync(string url)
{
if (string.IsNullOrWhiteSpace(url))
throw new ArgumentNullException(nameof(url));
var response = string.Empty;
using (var http = _httpFactory.CreateClient())
{
response = await http.GetStringAsync($"https://scapi.nadeko.bot/resolve?url={url}");
}
var responseObj = JsonConvert.DeserializeObject<SoundCloudVideo>(response);
if (responseObj?.Kind != "track")
throw new InvalidOperationException("Url is either not a track, or it doesn't exist.");
return responseObj;
}
public async Task<SoundCloudVideo> GetVideoByQueryAsync(string query)
{
if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query));
var response = string.Empty;
using (var http = _httpFactory.CreateClient())
{
response = await http.GetStringAsync(
new Uri($"https://scapi.nadeko.bot/tracks?q={Uri.EscapeDataString(query)}"));
}
var responseObj = JsonConvert.DeserializeObject<SoundCloudVideo[]>(response)
.FirstOrDefault(s => s.Streamable is true);
if (responseObj?.Kind != "track")
throw new InvalidOperationException("Query yielded no results.");
return responseObj;
}
}
public class SoundCloudVideo
{
public string Kind { get; set; } = string.Empty;
public long Id { get; set; } = 0;
public SoundCloudUser User { get; set; } = new();
public string Title { get; set; } = string.Empty;
public string FullName
=> User.Name + " - " + Title;
public bool? Streamable { get; set; } = false;
public int Duration { get; set; }
[JsonProperty("permalink_url")]
public string TrackLink { get; set; } = string.Empty;
[JsonProperty("artwork_url")]
public string ArtworkUrl { get; set; } = string.Empty;
}
public class SoundCloudUser
{
[JsonProperty("username")]
public string Name { get; set; }
}

View File

@@ -1,8 +0,0 @@
#nullable disable
namespace NadekoBot.Modules.Music;
public interface ISoundcloudResolver : IPlatformQueryResolver
{
bool IsSoundCloudLink(string url);
IAsyncEnumerable<ITrackInfo> ResolvePlaylistAsync(string playlist);
}

View File

@@ -6,5 +6,4 @@ public enum MusicPlatform
Radio,
Youtube,
Local,
SoundCloud
}

View File

@@ -1,84 +0,0 @@
using Newtonsoft.Json.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace NadekoBot.Modules.Music.Resolvers;
public sealed class SoundcloudResolver : ISoundcloudResolver
{
private readonly SoundCloudApiService _sc;
private readonly ITrackCacher _trackCacher;
private readonly IHttpClientFactory _httpFactory;
public SoundcloudResolver(SoundCloudApiService sc, ITrackCacher trackCacher, IHttpClientFactory httpFactory)
{
_sc = sc;
_trackCacher = trackCacher;
_httpFactory = httpFactory;
}
public bool IsSoundCloudLink(string url)
=> Regex.IsMatch(url, "(.*)(soundcloud.com|snd.sc)(.*)");
public async IAsyncEnumerable<ITrackInfo> ResolvePlaylistAsync(string playlist)
{
playlist = Uri.EscapeDataString(playlist);
using var http = _httpFactory.CreateClient();
var responseString = await http.GetStringAsync($"https://scapi.nadeko.bot/resolve?url={playlist}");
var scvids = JObject.Parse(responseString)["tracks"]?.ToObject<SoundCloudVideo[]>();
if (scvids is null)
yield break;
foreach (var videosChunk in scvids.Where(x => x.Streamable is true).Chunk(5))
{
var cachableTracks = videosChunk.Select(VideoModelToCachedData).ToList();
await cachableTracks.Select(_trackCacher.CacheTrackDataAsync).WhenAll();
foreach (var info in cachableTracks.Select(CachableDataToTrackInfo))
yield return info;
}
}
private ICachableTrackData VideoModelToCachedData(SoundCloudVideo svideo)
=> new CachableTrackData
{
Title = svideo.FullName,
Url = svideo.TrackLink,
Thumbnail = svideo.ArtworkUrl,
TotalDurationMs = svideo.Duration,
Id = svideo.Id.ToString(),
Platform = MusicPlatform.SoundCloud
};
private ITrackInfo CachableDataToTrackInfo(ICachableTrackData trackData)
=> new SimpleTrackInfo(trackData.Title,
trackData.Url,
trackData.Thumbnail,
trackData.Duration,
trackData.Platform,
GetStreamUrl(trackData.Id));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private string GetStreamUrl(string trackId)
=> $"https://api.soundcloud.com/tracks/{trackId}/stream?client_id=368b0c85751007cd588d869d3ae61ac0";
public async Task<ITrackInfo?> ResolveByQueryAsync(string query)
{
var cached = await _trackCacher.GetCachedDataByQueryAsync(query, MusicPlatform.SoundCloud);
if (cached is not null)
return CachableDataToTrackInfo(cached);
var svideo = !IsSoundCloudLink(query)
? await _sc.GetVideoByQueryAsync(query)
: await _sc.ResolveVideoAsync(query);
if (svideo is null)
return null;
var cachableData = VideoModelToCachedData(svideo);
await _trackCacher.CacheTrackDataByQueryAsync(query, cachableData);
return CachableDataToTrackInfo(cachableData);
}
}

View File

@@ -4,18 +4,15 @@ public sealed class TrackResolveProvider : ITrackResolveProvider
{
private readonly IYoutubeResolver _ytResolver;
private readonly ILocalTrackResolver _localResolver;
private readonly ISoundcloudResolver _soundcloudResolver;
private readonly IRadioResolver _radioResolver;
public TrackResolveProvider(
IYoutubeResolver ytResolver,
ILocalTrackResolver localResolver,
ISoundcloudResolver soundcloudResolver,
IRadioResolver radioResolver)
{
_ytResolver = ytResolver;
_localResolver = localResolver;
_soundcloudResolver = soundcloudResolver;
_radioResolver = radioResolver;
}
@@ -29,14 +26,10 @@ public sealed class TrackResolveProvider : ITrackResolveProvider
return _ytResolver.ResolveByQueryAsync(query);
case MusicPlatform.Local:
return _localResolver.ResolveByQueryAsync(query);
case MusicPlatform.SoundCloud:
return _soundcloudResolver.ResolveByQueryAsync(query);
case null:
var match = _ytResolver.YtVideoIdRegex.Match(query);
if (match.Success)
return _ytResolver.ResolveByIdAsync(match.Groups["id"].Value);
else if (_soundcloudResolver.IsSoundCloudLink(query))
return _soundcloudResolver.ResolveByQueryAsync(query);
else if (Uri.TryCreate(query, UriKind.Absolute, out var uri) && uri.IsFile)
return _localResolver.ResolveByQueryAsync(uri.AbsolutePath);
else if (IsRadioLink(query))

View File

@@ -37,7 +37,6 @@ public partial class Patronage : NadekoModule
Format.Bold(result.Failed.ToString())));
}
// [Cmd]
// [OwnerOnly]
// public async Task PatronGift(IUser user, int amount)
// {

View File

@@ -306,8 +306,7 @@ public partial class Utility : NadekoModule
}
[Cmd]
public async Task
Showemojis([Leftover] string _) // need to have the parameter so that the message.tags gets populated
public async Task Showemojis([Leftover] string _)
{
var tags = ctx.Message.Tags.Where(t => t.Type == TagType.Emoji).Select(t => (Emote)t.Value);
@@ -429,38 +428,6 @@ public partial class Utility : NadekoModule
using var http = _httpFactory.CreateClient();
stream = await http.GetStreamAsync(ss.GetStickerUrl());
}
// else if (ctx.Message.Attachments.FirstOrDefault() is { } attachment)
// {
// var url = attachment?.Url;
//
// if (url is null)
// return;
//
// if (name is null)
// {
// await ReplyErrorLocalizedAsync(strs.sticker_missing_name);
// return;
// }
//
// format = Path.GetExtension(attachment.Filename);
//
// if (attachment is not { Width: 300, Height: 300 })
// {
// await ReplyErrorLocalizedAsync(strs.sticker_invalid_size);
// return;
// }
//
// using var http = _httpFactory.CreateClient();
//
// using var res = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
// if (res.GetContentLength() > 512.Kilobytes().Bytes)
// {
// await ReplyErrorLocalizedAsync(strs.invalid_emoji_link);
// return;
// }
//
// stream = await res.Content.ReadAsStreamAsync();
// }
else
{
await ReplyErrorLocalizedAsync(strs.sticker_error);

View File

@@ -42,10 +42,8 @@ public abstract class NadekoContext : DbContext
public DbSet<DiscordUser> DiscordUser { get; set; }
public DbSet<MusicPlayerSettings> MusicPlayerSettings { get; set; }
public DbSet<Repeater> Repeaters { get; set; }
public DbSet<Poll> Poll { get; set; }
public DbSet<WaifuInfo> WaifuInfo { get; set; }
public DbSet<ImageOnlyChannel> ImageOnlyChannels { get; set; }
public DbSet<NsfwBlacklistedTag> NsfwBlacklistedTags { get; set; }
public DbSet<AutoTranslateChannel> AutoTranslateChannels { get; set; }
public DbSet<AutoTranslateUser> AutoTranslateUsers { get; set; }
@@ -285,12 +283,6 @@ public abstract class NadekoContext : DbContext
#endregion
#region Polls
modelBuilder.Entity<Poll>().HasIndex(x => x.GuildId).IsUnique();
#endregion
#region CurrencyTransactions
modelBuilder.Entity<CurrencyTransaction>(e =>
@@ -402,8 +394,6 @@ public abstract class NadekoContext : DbContext
modelBuilder.Entity<ImageOnlyChannel>(ioc => ioc.HasIndex(x => x.ChannelId).IsUnique());
modelBuilder.Entity<NsfwBlacklistedTag>(nbt => nbt.HasIndex(x => x.GuildId).IsUnique(false));
var atch = modelBuilder.Entity<AutoTranslateChannel>();
atch.HasIndex(x => x.GuildId).IsUnique(false);

View File

@@ -59,7 +59,6 @@ public static class ServiceCollectionExtensions
kernel.Bind<ITrackResolveProvider>().To<TrackResolveProvider>().InSingletonScope();
kernel.Bind<IYoutubeResolver>().To<YtdlYoutubeResolver>().InSingletonScope();
kernel.Bind<ISoundcloudResolver>().To<SoundcloudResolver>().InSingletonScope();
kernel.Bind<ILocalTrackResolver>().To<LocalTrackResolver>().InSingletonScope();
kernel.Bind<IRadioResolver>().To<RadioResolver>().InSingletonScope();
kernel.Bind<ITrackCacher>().To<TrackCacher>().InSingletonScope();

View File

@@ -418,8 +418,6 @@ typestop:
- typestop
typeadd:
- typeadd
pollend:
- pollend
pick:
- pick
plant:
@@ -434,8 +432,6 @@ choose:
- choose
rps:
- rps
linux:
- linux
next:
- next
- n
@@ -463,9 +459,6 @@ queuesearch:
- queuesearch
- qs
- yqs
soundcloudqueue:
- soundcloudqueue
- sq
listqueue:
- listqueue
- lq
@@ -479,9 +472,6 @@ volume:
playlist:
- playlist
- pl
soundcloudpl:
- soundcloudpl
- scpl
localplaylist:
- localplaylist
- lopl
@@ -651,8 +641,6 @@ chucknorris:
magicitem:
- magicitem
- mi
safebooru:
- safebooru
wiki:
- wiki
- wikipedia
@@ -662,25 +650,6 @@ color:
avatar:
- avatar
- av
hentai:
- hentai
danbooru:
- danbooru
derpibooru:
- derpibooru
- derpi
gelbooru:
- gelbooru
rule34:
- rule34
e621:
- e621
boobs:
- boobs
butts:
- butts
- ass
- butt
translate:
- translate
- trans
@@ -761,10 +730,6 @@ chatmute:
- chatmute
voicemute:
- voicemute
konachan:
- konachan
sankaku:
- sankaku
muterole:
- muterole
- setmuterole
@@ -782,9 +747,6 @@ placelist:
- placelist
place:
- place
poll:
- poll
- ppoll
autotranslang:
- autotranslang
- atl
@@ -801,8 +763,6 @@ typelist:
- typelist
listservers:
- listservers
hentaibomb:
- hentaibomb
cleverbot:
- cleverbot
- chatgpt
@@ -811,8 +771,6 @@ shorten:
wikia:
- wikia
- fandom
yandere:
- yandere
magicthegathering:
- magicthegathering
- mtg
@@ -837,8 +795,6 @@ define:
- def
activity:
- activity
autohentai:
- autohentai
setstatus:
- setstatus
invitecreate:
@@ -852,8 +808,6 @@ invitedelete:
- invitedelete
- invrm
- invdel
pollstats:
- pollstats
antilist:
- antilist
- antilst
@@ -923,8 +877,6 @@ languageset:
languageslist:
- languageslist
- langli
rategirl:
- rategirl
aliaslist:
- aliaslist
- cmdmaplist
@@ -1059,9 +1011,6 @@ configreload:
- creload
- confreload
- crel
nsfwtagblacklist:
- nsfwtagbl
- nsfwtbl
experience:
- experience
- xp
@@ -1141,10 +1090,6 @@ clubleaderboard:
- clubs
clubadmin:
- clubadmin
autoboobs:
- autoboobs
autobutts:
- autobutts
eightball:
- eightball
- 8ball
@@ -1253,10 +1198,9 @@ delete:
roleid:
- roleid
- rid
nsfwtoggle:
agerestricttoggle:
- nsfwtoggle
- nsfw
- nsfwtgl
- artoggle
economy:
- economy
purgeuser:
@@ -1410,7 +1354,7 @@ giveawaylist:
- list
# todos
todoadd:
- add
- add
- a
todolist:
- list

View File

@@ -800,10 +800,6 @@ rps:
args:
- "r 100"
- "scissors"
linux:
desc: "Prints a customizable Linux interjection"
args:
- "Spyware Windows"
next:
desc: "Goes to the next song in the queue. You have to be in the same voice channel as the bot"
args:
@@ -838,10 +834,6 @@ queuesearch:
desc: "Search for top 5 youtube song result using keywords, and type the index of the song to play that song. Bot will join your voice channel. **You must be in a voice channel**."
args:
- "Dream Of Venice"
soundcloudqueue:
desc: "Queue a soundcloud song using keywords. Bot will join your voice channel. **You must be in a voice channel**."
args:
- "Dream Of Venice"
listqueue:
desc: "Lists 10 currently queued songs per page. Default page is 1."
args:
@@ -859,11 +851,6 @@ playlist:
desc: "Queues up to 500 songs from a youtube playlist specified by a link, or keywords."
args:
- "<youtube_playlist_link>"
soundcloudpl:
desc: "Queue a Soundcloud playlist using a link."
args:
- "https://soundcloud.com/classical-music-playlist/sets/classical-music-essential-collection"
- "<soundcloud_set_link>"
localplaylist:
desc: "Queues all songs from a directory."
args:
@@ -1117,59 +1104,6 @@ avatar:
desc: "Shows a mentioned person's avatar."
args:
- "@Someone"
hentai:
desc: "Shows a hentai image from a random website (gelbooru, danbooru, konachan or yandere) with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags. Only 1 tag allowed."
args:
- "yuri"
autohentai:
desc: "Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tag groups. Random group will be chosen every time the image is sent. Max 2 tags per group. 20 seconds minimum. Provide no parameters to disable."
args:
- "30 yuri kissing|tail long_hair"
- ""
hentaibomb:
desc: "Shows a total 5 images (from gelbooru, danbooru, konachan and yandere). Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri"
yandere:
desc: "Shows a random image from yandere with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
danbooru:
desc: "Shows a random hentai image from danbooru with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
derpibooru:
desc: "Shows a random image from derpibooru with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
gelbooru:
desc: "Shows a random hentai image from gelbooru with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
sankaku:
desc: "Shows a random hentai image from chan.sankakucomplex.com with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kiss"
rule34:
desc: "Shows a random image from rule34.xx with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
e621:
desc: "Shows a random hentai image from e621.net with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
safebooru:
desc: "Shows a random image from safebooru with a given tag. Tag(s) are optional but preferred. Maximum is usually 2 tags."
args:
- "yuri kissing"
boobs:
desc: "Real adult content."
args:
- ""
butts:
desc: "Real adult content."
args:
- ""
translate:
desc: "Translates text from the given language to the destination language."
args:
@@ -1581,10 +1515,6 @@ languageslist:
desc: "List of languages for which translation (or part of it) exist atm."
args:
- ""
rategirl:
desc: "Use the universal hot-crazy wife zone matrix to determine the girl's worth. It is everything young men need to know about women. At any moment in time, any woman you have previously located on this chart can vanish from that location and appear anywhere else on the chart."
args:
- "@SomeGurl"
exprtoggleglobal:
desc: "Toggles whether global expressions are usable on this server."
args:
@@ -1640,7 +1570,6 @@ alias:
desc: "Create a custom alias for a certain Nadeko command. Provide no alias to remove the existing one."
args:
- "allin {0}bf all h"
- "\"linux thingy\" >loonix Spyware Windows"
warnlog:
desc: "See a list of warnings of a certain user."
args:
@@ -1986,16 +1915,6 @@ clubadmin:
desc: "Assigns (or unassigns) staff role to the member of the club. Admins can ban, kick and accept applications."
args:
- "@Someone"
autoboobs:
desc: "Posts a boobs every X seconds. 20 seconds minimum. Provide no parameters to disable."
args:
- "30"
- ""
autobutts:
desc: "Posts a butt every X seconds. 20 seconds minimum. Provide no parameters to disable."
args:
- "30"
- ""
eightball:
desc: "Ask the 8ball a yes/no question."
args:
@@ -2232,8 +2151,8 @@ roleid:
desc: "Shows the id of the specified role."
args:
- "Some Role"
nsfwtoggle:
desc: "Toggles the NSFW parameter of the current text channel."
agerestricttoggle:
desc: "Toggles whether the current channel is age-restricted."
args:
- ""
economy:

View File

@@ -986,7 +986,7 @@
"module_description_gambling": "Bet on dice rolls, blackjack, slots, coinflips and others",
"module_description_games": "Play trivia, nunchi, hangman, connect4 and other games",
"module_description_nsfw": "NSFW commands.",
"module_description_music": "Play music from youtube, local files soundcloud and radio streams",
"module_description_music": "Play music from youtube, local files and radio streams",
"module_description_utility": "Manage custom quotes, repeating messages and check facts about the server",
"module_description_administration": "Moderation, punish users, setup self assignable roles and greet messages",
"module_description_expressions": "Setup custom bot responses to certain words or phrases",