- Re-added .qap / .queueautoplay

- Several strings and commands related to music have been changed
  - Changed .ms / .movesong to .tm / .trackmove but kept old aliases
  - Changed ~~song~~ -> 	rack throughout music module strings
- Updated CHANGELOG.md
This commit is contained in:
Kwoth
2022-02-13 15:49:48 +01:00
parent 6895c8a2a4
commit 7ed1b13e85
20 changed files with 3054 additions and 181 deletions

View File

@@ -5,8 +5,6 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
## Unreleased ## Unreleased
## Changes
### Added ### Added
- Added `.deleteemptyservers` command - Added `.deleteemptyservers` command
- Added `.curtr <id>` which lets you see full information about one of your own transactions with the specified id - Added `.curtr <id>` which lets you see full information about one of your own transactions with the specified id
@@ -18,16 +16,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- waifu.decay.minPrice - Unclaimed waifus with price lower than the one specified here will not be affected by the decay - waifu.decay.minPrice - Unclaimed waifus with price lower than the one specified here will not be affected by the decay
- Added `currency.transactionsLifetime` to `data/gambling.yml` Any transaction older than the number of days specified will be automatically deleted - Added `currency.transactionsLifetime` to `data/gambling.yml` Any transaction older than the number of days specified will be automatically deleted
- Added `.stock` command to check stock prices and charts - Added `.stock` command to check stock prices and charts
- Re-added `.qap / .queueautoplay`
### Fixed
- Fixed an extra whitespace in usage part of command help if the command has no arguments
- Possible small fix for `.prune` ratelimiting
- `.gvc` should now properly trigger when a user is already in a gvc and changes his activity
- `.gvc` should now properly detect multiple activities
- Fixed reference to non-existent command in bot.yml
- Comment indentation in .yml files should now make more sense
- Fixed `.warn` punishments not being applied properly when using weighted warnings
- Fixed embed color when disabling `.antialt`
### Changed ### Changed
- CustomReactions module (and customreactions db table) has been renamed to Expressions. - CustomReactions module (and customreactions db table) has been renamed to Expressions.
@@ -41,6 +30,9 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- Currency output format improvement (will use guild locale now for some commands) - Currency output format improvement (will use guild locale now for some commands)
- `.crypto` will now also show CoinMarketCap rank - `.crypto` will now also show CoinMarketCap rank
- Waifus can now be claimed for much higher prices (int -> long) - Waifus can now be claimed for much higher prices (int -> long)
- Several strings and commands related to music have been changed
- Changed `.ms / .movesong` to `.tm / .trackmove` but kept old aliases
- Changed ~~song~~ -> `track` throughout music module strings
- Improved .curtrs (It will now have a lot more useful data in the database, show Tx ids, and be partially localized) - Improved .curtrs (It will now have a lot more useful data in the database, show Tx ids, and be partially localized)
- [dev] Reason renamed to Note - [dev] Reason renamed to Note
- [dev] Added Type, Extra, OtherId fields to the database - [dev] Added Type, Extra, OtherId fields to the database
@@ -50,20 +42,30 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- [dev] Permissionv2 db table renamed to Permissions - [dev] Permissionv2 db table renamed to Permissions
- [dev] Moved FilterWordsChannelId to a separate table - [dev] Moved FilterWordsChannelId to a separate table
### Fixed
- Fixed an extra whitespace in usage part of command help if the command has no arguments
- Possible small fix for `.prune` ratelimiting
- `.gvc` should now properly trigger when a user is already in a gvc and changes his activity
- `.gvc` should now properly detect multiple activities
- Fixed reference to non-existent command in bot.yml
- Comment indentation in .yml files should now make more sense
- Fixed `.warn` punishments not being applied properly when using weighted warnings
- Fixed embed color when disabling `.antialt`
### Removed ### Removed
- Removed `.bce` - use `.config` or `.config bot` specifically for bot config - Removed `.bce` - use `.config` or `.config bot` specifically for bot config
- Removed obsolete placeholders: %users% %servers% %userfull% %username% %userdiscrim% %useravatar% %id% %uid% %chname% %cid% %sid% %members% %server_time% %shardid% %time% %mention% - Removed obsolete placeholders: %users% %servers% %userfull% %username% %userdiscrim% %useravatar% %id% %uid% %chname% %cid% %sid% %members% %server_time% %shardid% %time% %mention%
- Removed some obsolete commands and strings - Removed some obsolete commands and strings
- Removed code which migrated 2.x to v3 credentials, settings, etc... - Removed code which migrated 2.x to v3 credentials, settings, etc...
## [3.0.13] - 14.04.2021 ## [3.0.13] - 14.01.2022
### Fixed ### Fixed
- Fixed `.greetdm` causing ratelimits during raids - Fixed `.greetdm` causing ratelimits during raids
- Fixed `.gelbooru` - Fixed `.gelbooru`
## [3.0.12] - 06.01.2021 ## [3.0.12] - 06.01.2022
### Fixed ### Fixed
- `.smch` Fixed - `.smch` Fixed

View File

@@ -38,6 +38,11 @@ public class MusicPlayerSettings
/// Selected quality preset for the music player /// Selected quality preset for the music player
/// </summary> /// </summary>
public QualityPreset QualityPreset { get; set; } public QualityPreset QualityPreset { get; set; }
/// <summary>
/// Whether the bot will automatically queue related songs
/// </summary>
public bool AutoPlay { get; set; }
} }
public enum QualityPreset public enum QualityPreset

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
public partial class musicautoplay : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// these 2 settings weren't being used for a long time
migrationBuilder.DropColumn(
name: "AutoDeleteByeMessages",
table: "GuildConfigs");
migrationBuilder.DropColumn(
name: "AutoDeleteGreetMessages",
table: "GuildConfigs");
migrationBuilder.AlterColumn<long>(
name: "Weight",
table: "Warnings",
type: "INTEGER",
nullable: false,
defaultValue: 1L,
oldClrType: typeof(int),
oldType: "INTEGER",
oldDefaultValue: 1);
migrationBuilder.AddColumn<bool>(
name: "AutoPlay",
table: "MusicPlayerSettings",
type: "INTEGER",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AutoPlay",
table: "MusicPlayerSettings");
migrationBuilder.AlterColumn<int>(
name: "Weight",
table: "Warnings",
type: "INTEGER",
nullable: false,
defaultValue: 1,
oldClrType: typeof(long),
oldType: "INTEGER",
oldDefaultValue: 1L);
migrationBuilder.AddColumn<bool>(
name: "AutoDeleteByeMessages",
table: "GuildConfigs",
type: "INTEGER",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "AutoDeleteGreetMessages",
table: "GuildConfigs",
type: "INTEGER",
nullable: false,
defaultValue: false);
}
}
}

View File

@@ -15,7 +15,7 @@ namespace NadekoBot.Migrations
protected override void BuildModel(ModelBuilder modelBuilder) protected override void BuildModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "6.0.1"); modelBuilder.HasAnnotation("ProductVersion", "6.0.2");
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
{ {
@@ -29,7 +29,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("ClubApplicants", (string)null); b.ToTable("ClubApplicants");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b =>
@@ -44,7 +44,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("ClubBans", (string)null); b.ToTable("ClubBans");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
@@ -86,7 +86,7 @@ namespace NadekoBot.Migrations
b.HasIndex("OwnerId") b.HasIndex("OwnerId")
.IsUnique(); .IsUnique();
b.ToTable("Clubs", (string)null); b.ToTable("Clubs");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b => modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b =>
@@ -155,7 +155,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("DiscordUser", (string)null); b.ToTable("DiscordUser");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b => modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
@@ -189,7 +189,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream", (string)null); b.ToTable("FollowedStream");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiAltSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiAltSetting", b =>
@@ -218,7 +218,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("AntiAltSetting", (string)null); b.ToTable("AntiAltSetting");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
@@ -250,7 +250,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("AntiRaidSetting", (string)null); b.ToTable("AntiRaidSetting");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b =>
@@ -272,7 +272,7 @@ namespace NadekoBot.Migrations
b.HasIndex("AntiSpamSettingId"); b.HasIndex("AntiSpamSettingId");
b.ToTable("AntiSpamIgnore", (string)null); b.ToTable("AntiSpamIgnore");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b =>
@@ -304,7 +304,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("AntiSpamSetting", (string)null); b.ToTable("AntiSpamSetting");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoCommand", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoCommand", b =>
@@ -342,7 +342,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("AutoCommands", (string)null); b.ToTable("AutoCommands");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b =>
@@ -370,7 +370,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId"); b.HasIndex("GuildId");
b.ToTable("AutoTranslateChannels", (string)null); b.ToTable("AutoTranslateChannels");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b =>
@@ -398,7 +398,7 @@ namespace NadekoBot.Migrations
b.HasAlternateKey("ChannelId", "UserId"); b.HasAlternateKey("ChannelId", "UserId");
b.ToTable("AutoTranslateUsers", (string)null); b.ToTable("AutoTranslateUsers");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b =>
@@ -421,7 +421,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("BanTemplates", (string)null); b.ToTable("BanTemplates");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistEntry", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistEntry", b =>
@@ -441,7 +441,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Blacklist", (string)null); b.ToTable("Blacklist");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b =>
@@ -466,7 +466,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("CommandAlias", (string)null); b.ToTable("CommandAlias");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
@@ -491,7 +491,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("CommandCooldown", (string)null); b.ToTable("CommandCooldown");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
@@ -529,7 +529,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("CurrencyTransactions", (string)null); b.ToTable("CurrencyTransactions");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.DelMsgOnCmdChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.DelMsgOnCmdChannel", b =>
@@ -554,7 +554,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("DelMsgOnCmdChannel", (string)null); b.ToTable("DelMsgOnCmdChannel");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordPermOverride", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordPermOverride", b =>
@@ -580,7 +580,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId", "Command") b.HasIndex("GuildId", "Command")
.IsUnique(); .IsUnique();
b.ToTable("DiscordPermOverrides", (string)null); b.ToTable("DiscordPermOverrides");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ExcludedItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ExcludedItem", b =>
@@ -605,7 +605,7 @@ namespace NadekoBot.Migrations
b.HasIndex("XpSettingsId"); b.HasIndex("XpSettingsId");
b.ToTable("ExcludedItem", (string)null); b.ToTable("ExcludedItem");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FeedSub", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FeedSub", b =>
@@ -631,7 +631,7 @@ namespace NadekoBot.Migrations
b.HasAlternateKey("GuildConfigId", "Url"); b.HasAlternateKey("GuildConfigId", "Url");
b.ToTable("FeedSub", (string)null); b.ToTable("FeedSub");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
@@ -653,7 +653,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FilterChannelId", (string)null); b.ToTable("FilterChannelId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
@@ -675,7 +675,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FilteredWord", (string)null); b.ToTable("FilteredWord");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterLinksChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterLinksChannelId", b =>
@@ -697,7 +697,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FilterLinksChannelId", (string)null); b.ToTable("FilterLinksChannelId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterWordsChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterWordsChannelId", b =>
@@ -719,7 +719,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FilterWordsChannelId", (string)null); b.ToTable("FilterWordsChannelId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
@@ -741,7 +741,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("GCChannelId", (string)null); b.ToTable("GCChannelId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.GroupName", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.GroupName", b =>
@@ -767,7 +767,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId", "Number") b.HasIndex("GuildConfigId", "Number")
.IsUnique(); .IsUnique();
b.ToTable("GroupName", (string)null); b.ToTable("GroupName");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
@@ -779,15 +779,9 @@ namespace NadekoBot.Migrations
b.Property<string>("AutoAssignRoleIds") b.Property<string>("AutoAssignRoleIds")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<bool>("AutoDeleteByeMessages")
.HasColumnType("INTEGER");
b.Property<int>("AutoDeleteByeMessagesTimer") b.Property<int>("AutoDeleteByeMessagesTimer")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("AutoDeleteGreetMessages")
.HasColumnType("INTEGER");
b.Property<int>("AutoDeleteGreetMessagesTimer") b.Property<int>("AutoDeleteGreetMessagesTimer")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@@ -897,7 +891,7 @@ namespace NadekoBot.Migrations
b.HasIndex("WarnExpireHours"); b.HasIndex("WarnExpireHours");
b.ToTable("GuildConfigs", (string)null); b.ToTable("GuildConfigs");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogItem", b =>
@@ -923,7 +917,7 @@ namespace NadekoBot.Migrations
b.HasIndex("LogSettingId", "LogItemId", "ItemType") b.HasIndex("LogSettingId", "LogItemId", "ItemType")
.IsUnique(); .IsUnique();
b.ToTable("IgnoredLogChannels", (string)null); b.ToTable("IgnoredLogChannels");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
@@ -945,7 +939,7 @@ namespace NadekoBot.Migrations
b.HasIndex("LogSettingId"); b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels", (string)null); b.ToTable("IgnoredVoicePresenceCHannels");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ImageOnlyChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ImageOnlyChannel", b =>
@@ -968,7 +962,7 @@ namespace NadekoBot.Migrations
b.HasIndex("ChannelId") b.HasIndex("ChannelId")
.IsUnique(); .IsUnique();
b.ToTable("ImageOnlyChannels", (string)null); b.ToTable("ImageOnlyChannels");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
@@ -1033,7 +1027,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("LogSettings", (string)null); b.ToTable("LogSettings");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlayerSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlayerSettings", b =>
@@ -1045,6 +1039,9 @@ namespace NadekoBot.Migrations
b.Property<bool>("AutoDisconnect") b.Property<bool>("AutoDisconnect")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("AutoPlay")
.HasColumnType("INTEGER");
b.Property<ulong>("GuildId") b.Property<ulong>("GuildId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@@ -1067,7 +1064,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("MusicPlayerSettings", (string)null); b.ToTable("MusicPlayerSettings");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
@@ -1090,7 +1087,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("MusicPlaylists", (string)null); b.ToTable("MusicPlaylists");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
@@ -1112,7 +1109,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("MutedUserId", (string)null); b.ToTable("MutedUserId");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.NadekoExpression", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.NadekoExpression", b =>
@@ -1150,7 +1147,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Expressions", (string)null); b.ToTable("Expressions");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklistedTag", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklistedTag", b =>
@@ -1172,7 +1169,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId"); b.HasIndex("GuildId");
b.ToTable("NsfwBlacklistedTags", (string)null); b.ToTable("NsfwBlacklistedTags");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b =>
@@ -1212,7 +1209,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("Permissions", (string)null); b.ToTable("Permissions");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlantedCurrency", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PlantedCurrency", b =>
@@ -1249,7 +1246,7 @@ namespace NadekoBot.Migrations
b.HasIndex("MessageId") b.HasIndex("MessageId")
.IsUnique(); .IsUnique();
b.ToTable("PlantedCurrency", (string)null); b.ToTable("PlantedCurrency");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
@@ -1283,7 +1280,7 @@ namespace NadekoBot.Migrations
b.HasIndex("MusicPlaylistId"); b.HasIndex("MusicPlaylistId");
b.ToTable("PlaylistSong", (string)null); b.ToTable("PlaylistSong");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Poll", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Poll", b =>
@@ -1309,7 +1306,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("Poll", (string)null); b.ToTable("Poll");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PollAnswer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PollAnswer", b =>
@@ -1334,7 +1331,7 @@ namespace NadekoBot.Migrations
b.HasIndex("PollId"); b.HasIndex("PollId");
b.ToTable("PollAnswer", (string)null); b.ToTable("PollAnswer");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PollVote", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PollVote", b =>
@@ -1359,7 +1356,7 @@ namespace NadekoBot.Migrations
b.HasIndex("PollId"); b.HasIndex("PollId");
b.ToTable("PollVote", (string)null); b.ToTable("PollVote");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
@@ -1395,7 +1392,7 @@ namespace NadekoBot.Migrations
b.HasIndex("Keyword"); b.HasIndex("Keyword");
b.ToTable("Quotes", (string)null); b.ToTable("Quotes");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRole", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRole", b =>
@@ -1420,7 +1417,7 @@ namespace NadekoBot.Migrations
b.HasIndex("ReactionRoleMessageId"); b.HasIndex("ReactionRoleMessageId");
b.ToTable("ReactionRole", (string)null); b.ToTable("ReactionRole");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRoleMessage", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRoleMessage", b =>
@@ -1451,7 +1448,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("ReactionRoleMessage", (string)null); b.ToTable("ReactionRoleMessage");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
@@ -1485,7 +1482,7 @@ namespace NadekoBot.Migrations
b.HasIndex("When"); b.HasIndex("When");
b.ToTable("Reminders", (string)null); b.ToTable("Reminders");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
@@ -1520,7 +1517,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Repeaters", (string)null); b.ToTable("Repeaters");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b =>
@@ -1549,7 +1546,7 @@ namespace NadekoBot.Migrations
b.HasIndex("PatreonUserId") b.HasIndex("PatreonUserId")
.IsUnique(); .IsUnique();
b.ToTable("RewardedUsers", (string)null); b.ToTable("RewardedUsers");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.RotatingPlayingStatus", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.RotatingPlayingStatus", b =>
@@ -1569,7 +1566,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("RotatingStatus", (string)null); b.ToTable("RotatingStatus");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
@@ -1600,7 +1597,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId", "RoleId") b.HasIndex("GuildId", "RoleId")
.IsUnique(); .IsUnique();
b.ToTable("SelfAssignableRoles", (string)null); b.ToTable("SelfAssignableRoles");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b =>
@@ -1640,7 +1637,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("ShopEntry", (string)null); b.ToTable("ShopEntry");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b =>
@@ -1662,7 +1659,7 @@ namespace NadekoBot.Migrations
b.HasIndex("ShopEntryId"); b.HasIndex("ShopEntryId");
b.ToTable("ShopEntryItem", (string)null); b.ToTable("ShopEntryItem");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b =>
@@ -1684,7 +1681,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("SlowmodeIgnoredRole", (string)null); b.ToTable("SlowmodeIgnoredRole");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b =>
@@ -1706,7 +1703,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("SlowmodeIgnoredUser", (string)null); b.ToTable("SlowmodeIgnoredUser");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b =>
@@ -1731,7 +1728,7 @@ namespace NadekoBot.Migrations
b.HasIndex("StreamRoleSettingsId"); b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleBlacklistedUser", (string)null); b.ToTable("StreamRoleBlacklistedUser");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
@@ -1763,7 +1760,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("StreamRoleSettings", (string)null); b.ToTable("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b =>
@@ -1788,7 +1785,7 @@ namespace NadekoBot.Migrations
b.HasIndex("StreamRoleSettingsId"); b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleWhitelistedUser", (string)null); b.ToTable("StreamRoleWhitelistedUser");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnbanTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnbanTimer", b =>
@@ -1813,7 +1810,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("UnbanTimer", (string)null); b.ToTable("UnbanTimer");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
@@ -1838,7 +1835,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("UnmuteTimer", (string)null); b.ToTable("UnmuteTimer");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnroleTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnroleTimer", b =>
@@ -1866,7 +1863,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("UnroleTimer", (string)null); b.ToTable("UnroleTimer");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserXpStats", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UserXpStats", b =>
@@ -1911,7 +1908,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId", "GuildId") b.HasIndex("UserId", "GuildId")
.IsUnique(); .IsUnique();
b.ToTable("UserXpStats", (string)null); b.ToTable("UserXpStats");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b =>
@@ -1936,7 +1933,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("VcRoleInfo", (string)null); b.ToTable("VcRoleInfo");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
@@ -1954,7 +1951,7 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded") b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<int>("Price") b.Property<long>("Price")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("WaifuId") b.Property<int>("WaifuId")
@@ -1971,7 +1968,7 @@ namespace NadekoBot.Migrations
b.HasIndex("WaifuId") b.HasIndex("WaifuId")
.IsUnique(); .IsUnique();
b.ToTable("WaifuInfo", (string)null); b.ToTable("WaifuInfo");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuItem", b =>
@@ -1996,7 +1993,7 @@ namespace NadekoBot.Migrations
b.HasIndex("WaifuInfoId"); b.HasIndex("WaifuInfoId");
b.ToTable("WaifuItem", (string)null); b.ToTable("WaifuItem");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b =>
@@ -2028,7 +2025,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("WaifuUpdates", (string)null); b.ToTable("WaifuUpdates");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b =>
@@ -2058,10 +2055,10 @@ namespace NadekoBot.Migrations
b.Property<ulong>("UserId") b.Property<ulong>("UserId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("Weight") b.Property<long>("Weight")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER") .HasColumnType("INTEGER")
.HasDefaultValue(1); .HasDefaultValue(1L);
b.HasKey("Id"); b.HasKey("Id");
@@ -2071,7 +2068,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("Warnings", (string)null); b.ToTable("Warnings");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b =>
@@ -2102,7 +2099,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("WarningPunishment", (string)null); b.ToTable("WarningPunishment");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpCurrencyReward", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.XpCurrencyReward", b =>
@@ -2127,7 +2124,7 @@ namespace NadekoBot.Migrations
b.HasIndex("XpSettingsId"); b.HasIndex("XpSettingsId");
b.ToTable("XpCurrencyReward", (string)null); b.ToTable("XpCurrencyReward");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b =>
@@ -2156,7 +2153,7 @@ namespace NadekoBot.Migrations
b.HasIndex("XpSettingsId", "Level") b.HasIndex("XpSettingsId", "Level")
.IsUnique(); .IsUnique();
b.ToTable("XpRoleReward", (string)null); b.ToTable("XpRoleReward");
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b =>
@@ -2179,7 +2176,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("XpSettings", (string)null); b.ToTable("XpSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>

View File

@@ -103,7 +103,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
var (trackInfo, index) = await mp.TryEnqueueTrackAsync(query, ctx.User.ToString(), asNext, forcePlatform); var (trackInfo, index) = await mp.TryEnqueueTrackAsync(query, ctx.User.ToString(), asNext, forcePlatform);
if (trackInfo is null) if (trackInfo is null)
{ {
await ReplyErrorLocalizedAsync(strs.song_not_found); await ReplyErrorLocalizedAsync(strs.track_not_found);
return; return;
} }
@@ -111,7 +111,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
{ {
var embed = _eb.Create() var embed = _eb.Create()
.WithOkColor() .WithOkColor()
.WithAuthor(GetText(strs.queued_song) + " #" + (index + 1), MUSIC_ICON_URL) .WithAuthor(GetText(strs.queued_track) + " #" + (index + 1), MUSIC_ICON_URL)
.WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ") .WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ")
.WithFooter(trackInfo.Platform.ToString()); .WithFooter(trackInfo.Platform.ToString());
@@ -248,7 +248,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async partial Task ListQueue() public async partial Task ListQueue()
{ {
// show page with the current song // show page with the current track
if (!_service.TryGetMusicPlayer(ctx.Guild.Id, out var mp)) if (!_service.TryGetMusicPlayer(ctx.Guild.Id, out var mp))
{ {
await ReplyErrorLocalizedAsync(strs.no_player); await ReplyErrorLocalizedAsync(strs.no_player);
@@ -291,8 +291,8 @@ public sealed partial class Music : NadekoModule<IMusicService>
add += "🔂 " + GetText(strs.repeating_track) + "\n"; add += "🔂 " + GetText(strs.repeating_track) + "\n";
else else
{ {
// if (mp.Autoplay) if (mp.AutoPlay)
// add += "↪ " + GetText(strs.autoplaying) + "\n"; add += "↪ " + GetText(strs.autoplaying) + "\n";
// if (mp.FairPlay && !mp.Autoplay) // if (mp.FairPlay && !mp.Autoplay)
// add += " " + GetText(strs.fairplay) + "\n"; // add += " " + GetText(strs.fairplay) + "\n";
if (repeatType == PlayerRepeatType.Queue) if (repeatType == PlayerRepeatType.Queue)
@@ -339,7 +339,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
if (videos.Count == 0) if (videos.Count == 0)
{ {
await ReplyErrorLocalizedAsync(strs.song_not_found); await ReplyErrorLocalizedAsync(strs.track_not_found);
return; return;
} }
@@ -388,7 +388,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
{ {
if (index < 1) if (index < 1)
{ {
await ReplyErrorLocalizedAsync(strs.removed_song_error); await ReplyErrorLocalizedAsync(strs.removed_track_error);
return; return;
} }
@@ -402,16 +402,16 @@ public sealed partial class Music : NadekoModule<IMusicService>
return; return;
} }
if (!mp.TryRemoveTrackAt(index - 1, out var song)) if (!mp.TryRemoveTrackAt(index - 1, out var track))
{ {
await ReplyErrorLocalizedAsync(strs.removed_song_error); await ReplyErrorLocalizedAsync(strs.removed_track_error);
return; return;
} }
var embed = _eb.Create() var embed = _eb.Create()
.WithAuthor(GetText(strs.removed_song) + " #" + index, MUSIC_ICON_URL) .WithAuthor(GetText(strs.removed_track) + " #" + index, MUSIC_ICON_URL)
.WithDescription(song.PrettyName()) .WithDescription(track.PrettyName())
.WithFooter(song.PrettyInfo()) .WithFooter(track.PrettyInfo())
.WithErrorColor(); .WithErrorColor();
await _service.SendToOutputAsync(ctx.Guild.Id, embed); await _service.SendToOutputAsync(ctx.Guild.Id, embed);
@@ -550,7 +550,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async partial Task MoveSong(int from, int to) public async partial Task TrackMove(int from, int to)
{ {
if (--from < 0 || --to < 0 || from == to) if (--from < 0 || --to < 0 || from == to)
{ {
@@ -578,7 +578,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
var embed = _eb.Create() var embed = _eb.Create()
.WithTitle(track.Title.TrimTo(65)) .WithTitle(track.Title.TrimTo(65))
.WithAuthor(GetText(strs.song_moved), MUSIC_ICON_URL) .WithAuthor(GetText(strs.track_moved), MUSIC_ICON_URL)
.AddField(GetText(strs.from_position), $"#{from + 1}", true) .AddField(GetText(strs.from_position), $"#{from + 1}", true)
.AddField(GetText(strs.to_position), $"#{to + 1}", true) .AddField(GetText(strs.to_position), $"#{to + 1}", true)
.WithOkColor(); .WithOkColor();
@@ -744,4 +744,15 @@ public sealed partial class Music : NadekoModule<IMusicService>
await _service.SetMusicQualityAsync(ctx.Guild.Id, preset); await _service.SetMusicQualityAsync(ctx.Guild.Id, preset);
await ReplyConfirmLocalizedAsync(strs.music_quality_set(Format.Bold(preset.ToString()))); await ReplyConfirmLocalizedAsync(strs.music_quality_set(Format.Bold(preset.ToString())));
} }
[Cmd]
[RequireContext(ContextType.Guild)]
public async partial Task QueueAutoPlay()
{
var newValue = await _service.ToggleQueueAutoPlayAsync(ctx.Guild.Id);
if (newValue)
await ReplyConfirmLocalizedAsync(strs.music_autoplay_on);
else
await ReplyConfirmLocalizedAsync(strs.music_autoplay_off);
}
} }

View File

@@ -32,4 +32,5 @@ public interface IMusicService : IPlaceholderProvider
Task<bool> ToggleAutoDisconnectAsync(ulong guildId); Task<bool> ToggleAutoDisconnectAsync(ulong guildId);
Task<QualityPreset> GetMusicQualityAsync(ulong guildId); Task<QualityPreset> GetMusicQualityAsync(ulong guildId);
Task SetMusicQualityAsync(ulong guildId, QualityPreset preset); Task SetMusicQualityAsync(ulong guildId, QualityPreset preset);
Task<bool> ToggleQueueAutoPlayAsync(ulong guildId);
} }

View File

@@ -156,7 +156,12 @@ public sealed class MusicService : IMusicService
_outputChannels[guildId] = (defaultChannel, overrideChannel); _outputChannels[guildId] = (defaultChannel, overrideChannel);
var mp = new MusicPlayer(queue, resolver, proxy, settings.QualityPreset); var mp = new MusicPlayer(queue,
resolver,
proxy,
_googleApiService,
settings.QualityPreset,
settings.AutoPlay);
mp.SetRepeat(settings.PlayerRepeat); mp.SetRepeat(settings.PlayerRepeat);
@@ -191,7 +196,7 @@ public sealed class MusicService : IMusicService
_ = lastFinishedMessage?.DeleteAsync(); _ = lastFinishedMessage?.DeleteAsync();
var embed = _eb.Create() var embed = _eb.Create()
.WithOkColor() .WithOkColor()
.WithAuthor(GetText(guildId, strs.finished_song), Music.MUSIC_ICON_URL) .WithAuthor(GetText(guildId, strs.finished_track), Music.MUSIC_ICON_URL)
.WithDescription(trackInfo.PrettyName()) .WithDescription(trackInfo.PrettyName())
.WithFooter(trackInfo.PrettyTotalTime()); .WithFooter(trackInfo.PrettyTotalTime());
@@ -207,7 +212,7 @@ public sealed class MusicService : IMusicService
_ = lastPlayingMessage?.DeleteAsync(); _ = lastPlayingMessage?.DeleteAsync();
var embed = _eb.Create() var embed = _eb.Create()
.WithOkColor() .WithOkColor()
.WithAuthor(GetText(guildId, strs.playing_song(index + 1)), Music.MUSIC_ICON_URL) .WithAuthor(GetText(guildId, strs.playing_track(index + 1)), Music.MUSIC_ICON_URL)
.WithDescription(trackInfo.PrettyName()) .WithDescription(trackInfo.PrettyName())
.WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}"); .WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}");
@@ -288,7 +293,7 @@ public sealed class MusicService : IMusicService
public IEnumerable<(string Name, Func<string> Func)> GetPlaceholders() public IEnumerable<(string Name, Func<string> Func)> GetPlaceholders()
{ {
// random song that's playing // random track that's playing
yield return ("%music.playing%", () => yield return ("%music.playing%", () =>
{ {
var randomPlayingTrack = _players.Select(x => x.Value.GetCurrentTrack(out _)) var randomPlayingTrack = _players.Select(x => x.Value.GetCurrentTrack(out _))
@@ -438,5 +443,17 @@ public sealed class MusicService : IMusicService
}, },
preset); preset);
public async Task<bool> ToggleQueueAutoPlayAsync(ulong guildId)
{
var newValue = false;
await ModifySettingsInternalAsync(guildId,
(settings, _) => newValue = settings.AutoPlay = !settings.AutoPlay,
false);
if (TryGetMusicPlayer(guildId, out var mp))
mp.AutoPlay = newValue;
return newValue;
}
#endregion #endregion
} }

View File

@@ -10,6 +10,7 @@ public interface IMusicPlayer : IDisposable
bool IsKilled { get; } bool IsKilled { get; }
int CurrentIndex { get; } int CurrentIndex { get; }
public PlayerRepeatType Repeat { get; } public PlayerRepeatType Repeat { get; }
bool AutoPlay { get; set; }
void Stop(); void Stop();
void Clear(); void Clear();

View File

@@ -2,6 +2,7 @@
public interface ITrackInfo public interface ITrackInfo
{ {
public string Id => string.Empty;
public string Title { get; } public string Title { get; }
public string Url { get; } public string Url { get; }
public string Thumbnail { get; } public string Thumbnail { get; }

View File

@@ -28,6 +28,7 @@ public sealed class MusicPlayer : IMusicPlayer
private readonly IMusicQueue _queue; private readonly IMusicQueue _queue;
private readonly ITrackResolveProvider _trackResolveProvider; private readonly ITrackResolveProvider _trackResolveProvider;
private readonly IVoiceProxy _proxy; private readonly IVoiceProxy _proxy;
private readonly IGoogleApiService _googleApiService;
private readonly ISongBuffer _songBuffer; private readonly ISongBuffer _songBuffer;
private bool skipped; private bool skipped;
@@ -35,15 +36,21 @@ public sealed class MusicPlayer : IMusicPlayer
private readonly Thread _thread; private readonly Thread _thread;
private readonly Random _rng; private readonly Random _rng;
public bool AutoPlay { get; set; }
public MusicPlayer( public MusicPlayer(
IMusicQueue queue, IMusicQueue queue,
ITrackResolveProvider trackResolveProvider, ITrackResolveProvider trackResolveProvider,
IVoiceProxy proxy, IVoiceProxy proxy,
QualityPreset qualityPreset) IGoogleApiService googleApiService,
QualityPreset qualityPreset,
bool autoPlay)
{ {
_queue = queue; _queue = queue;
_trackResolveProvider = trackResolveProvider; _trackResolveProvider = trackResolveProvider;
_proxy = proxy; _proxy = proxy;
_googleApiService = googleApiService;
AutoPlay = autoPlay;
_rng = new NadekoRandom(); _rng = new NadekoRandom();
_vc = GetVoiceClient(qualityPreset); _vc = GetVoiceClient(qualityPreset);
@@ -265,7 +272,29 @@ public sealed class MusicPlayer : IMusicPlayer
{ {
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
// turn off green in vc // turn off green in vc
_ = OnCompleted?.Invoke(this, track); _ = OnCompleted?.Invoke(this, track);
// todo update when settings are changed
if (AutoPlay && track.Platform == MusicPlatform.Youtube)
{
try
{
var relatedSongs = await _googleApiService.GetRelatedVideosAsync(track.TrackInfo.Id, 5);
var related = relatedSongs.Shuffle().FirstOrDefault();
if (related is not null)
{
var relatedTrack = await _trackResolveProvider.QuerySongAsync(related, MusicPlatform.Youtube);
if (relatedTrack is not null)
EnqueueTrack(relatedTrack, "Autoplay");
}
}
catch (Exception ex)
{
Log.Warning(ex, "Failed queueing a related song via autoplay");
}
}
HandleQueuePostTrack(); HandleQueuePostTrack();
skipped = false; skipped = false;

View File

@@ -1,30 +1,15 @@
namespace NadekoBot.Modules.Music; namespace NadekoBot.Modules.Music;
public sealed class RemoteTrackInfo : ITrackInfo public sealed record RemoteTrackInfo(
string Id,
string Title,
string Url,
string Thumbnail,
TimeSpan Duration,
MusicPlatform Platform,
Func<Task<string?>> _streamFactory) : ITrackInfo
{ {
public string Title { get; } private readonly Func<Task<string?>> _streamFactory = _streamFactory;
public string Url { get; }
public string Thumbnail { get; }
public TimeSpan Duration { get; }
public MusicPlatform Platform { get; }
private readonly Func<Task<string?>> _streamFactory;
public RemoteTrackInfo(
string title,
string url,
string thumbnail,
TimeSpan duration,
MusicPlatform platform,
Func<Task<string?>> streamFactory)
{
_streamFactory = streamFactory;
Title = title;
Url = url;
Thumbnail = thumbnail;
Duration = duration;
Platform = platform;
}
public async ValueTask<string?> GetStreamUrl() public async ValueTask<string?> GetStreamUrl()
=> await _streamFactory(); => await _streamFactory();

View File

@@ -94,7 +94,9 @@ public sealed class YtdlYoutubeResolver : IYoutubeResolver
} }
private ITrackInfo DataToInfo(in YtTrackData trackData) private ITrackInfo DataToInfo(in YtTrackData trackData)
=> new RemoteTrackInfo(trackData.Title, => new RemoteTrackInfo(
trackData.Id,
trackData.Title,
$"https://youtube.com/watch?v={trackData.Id}", $"https://youtube.com/watch?v={trackData.Id}",
trackData.Thumbnail, trackData.Thumbnail,
trackData.Duration, trackData.Duration,

View File

@@ -4,8 +4,6 @@ using System.Globalization;
namespace NadekoBot.Modules.Searches; namespace NadekoBot.Modules.Searches;
// todo weighted warnings fix
// todo autoplay/fairplay
public partial class Searches public partial class Searches
{ {
public partial class FinanceCommands : NadekoSubmodule<CryptoService> public partial class FinanceCommands : NadekoSubmodule<CryptoService>

View File

@@ -1,4 +1,5 @@
#nullable disable // #nullable disable
// using NadekoBot.Db.Models;
// using System; // using System;
// using System.Collections.Generic; // using System.Collections.Generic;
// using System.Linq; // using System.Linq;
@@ -10,6 +11,7 @@
// using NadekoBot.Services.Database.Models; // using NadekoBot.Services.Database.Models;
// using NadekoBot.Extensions; // using NadekoBot.Extensions;
// using Serilog; // using Serilog;
// using TwitchLib.Api;
// using JsonSerializer = System.Text.Json.JsonSerializer; // using JsonSerializer = System.Text.Json.JsonSerializer;
// //
// namespace NadekoBot.Modules.Searches.Common.StreamNotifications.Providers // namespace NadekoBot.Modules.Searches.Common.StreamNotifications.Providers
@@ -25,33 +27,17 @@
// public override FollowedStream.FType Platform => FollowedStream.FType.Twitch; // public override FollowedStream.FType Platform => FollowedStream.FType.Twitch;
// //
// private (string Token, DateTime Expiry) _token = default; // private (string Token, DateTime Expiry) _token = default;
// // private readonly TwitchAPI _api;
//
// public TwitchHelixProvider(IHttpClientFactory httpClientFactory) // public TwitchHelixProvider(IHttpClientFactory httpClientFactory)
// { // {
// _httpClientFactory = httpClientFactory; // _httpClientFactory = httpClientFactory;
// _api = new TwitchAPI();
// } // }
// //
// private async Task EnsureTokenValidAsync() // private async Task EnsureTokenValidAsync()
// { // => await _api.Auth.GetAccessTokenAsync();
// if (_token != default && (DateTime.UtcNow - _token.Expiry) > TimeSpan.FromHours(1))
// return;
// //
// const string clientId = string.Empty;
// const string clientSecret = string.Empty;
//
// var client = _httpClientFactory.CreateClient();
// var res = await client.PostAsync("https://id.twitch.tv/oauth2/token" +
// $"?client_id={clientId}" +
// $"&client_secret={clientSecret}" +
// "&grant_type=client_credentials", new StringContent(""));
//
// var data = JsonDocument.Parse(await res.Content.ReadAsStringAsync()).RootElement;
//
// _token = (data.GetProperty("access_token").GetString(),
// DateTime.UtcNow + TimeSpan.FromSeconds(data.GetProperty("expires_in").GetInt32()));
//
// }
//
// public override Task<bool> IsValidUrl(string url) // public override Task<bool> IsValidUrl(string url)
// { // {
// var match = Regex.Match(url); // var match = Regex.Match(url);

View File

@@ -10,7 +10,7 @@ public interface IGoogleApiService
Task<IEnumerable<string>> GetVideoLinksByKeywordAsync(string keywords, int count = 1); Task<IEnumerable<string>> GetVideoLinksByKeywordAsync(string keywords, int count = 1);
Task<IEnumerable<(string Name, string Id, string Url)>> GetVideoInfosByKeywordAsync(string keywords, int count = 1); Task<IEnumerable<(string Name, string Id, string Url)>> GetVideoInfosByKeywordAsync(string keywords, int count = 1);
Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1); Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1);
Task<IEnumerable<string>> GetRelatedVideosAsync(string url, int count = 1); Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1, string user = null);
Task<IEnumerable<string>> GetPlaylistTracksAsync(string playlistId, int count = 50); Task<IEnumerable<string>> GetPlaylistTracksAsync(string playlistId, int count = 50);
Task<IReadOnlyDictionary<string, TimeSpan>> GetVideoDurationsAsync(IEnumerable<string> videoIds); Task<IReadOnlyDictionary<string, TimeSpan>> GetVideoDurationsAsync(IEnumerable<string> videoIds);
Task<ImageResult> GetImageAsync(string query); Task<ImageResult> GetImageAsync(string query);

View File

@@ -194,8 +194,7 @@ public class GoogleApiService : IGoogleApiService, INService
return (await query.ExecuteAsync()).Items.Select(i => i.Id.PlaylistId); return (await query.ExecuteAsync()).Items.Select(i => i.Id.PlaylistId);
} }
// todo future add quota users public async Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1, string user = null)
public async Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1)
{ {
if (string.IsNullOrWhiteSpace(id)) if (string.IsNullOrWhiteSpace(id))
throw new ArgumentNullException(nameof(id)); throw new ArgumentNullException(nameof(id));
@@ -207,6 +206,7 @@ public class GoogleApiService : IGoogleApiService, INService
query.MaxResults = count; query.MaxResults = count;
query.RelatedToVideoId = id; query.RelatedToVideoId = id;
query.Type = "video"; query.Type = "video";
query.QuotaUser = user;
return (await query.ExecuteAsync()).Items.Select(i => "http://www.youtube.com/watch?v=" + i.Id.VideoId); return (await query.ExecuteAsync()).Items.Select(i => "http://www.youtube.com/watch?v=" + i.Id.VideoId);
} }

View File

@@ -472,13 +472,19 @@ trackremove:
- songremove - songremove
- srm - srm
- trackremove - trackremove
movesong: - trm
trackmove:
- trackmove
- tm
- movesong - movesong
- ms - ms
queuerepeat: queuerepeat:
- queuerepeat - queuerepeat
- qrp - qrp
- rpl - rpl
queueautoplay:
- queueautoplay
- qap
save: save:
- save - save
streamrole: streamrole:

View File

@@ -849,7 +849,7 @@ trackremove:
- "5" - "5"
- "all" - "all"
- "" - ""
movesong: trackmove:
desc: "Moves a song from one position to another." desc: "Moves a song from one position to another."
args: args:
- "5 3" - "5 3"
@@ -888,7 +888,7 @@ deleteplaylist:
desc: "Deletes a saved playlist using its id. Works only if you made it or if you are the bot owner." desc: "Deletes a saved playlist using its id. Works only if you made it or if you are the bot owner."
args: args:
- "5" - "5"
autoplay: queueautoplay:
desc: "Toggles autoplay - When the song is finished, automatically queue a related Youtube song. (Works only for Youtube songs and when queue is empty)" desc: "Toggles autoplay - When the song is finished, automatically queue a related Youtube song. (Works only for Youtube songs and when queue is empty)"
args: args:
- "" - ""

View File

@@ -354,10 +354,10 @@
"ttt_time_expired": "Time expired!", "ttt_time_expired": "Time expired!",
"ttt_users_move": "{0}'s move", "ttt_users_move": "{0}'s move",
"vs": "{0} vs {1}", "vs": "{0} vs {1}",
"attempting_to_queue": "Attempting to queue {0} songs...", "attempting_to_queue": "Attempting to queue {0} tracks...",
"dir_queue_complete": "Directory queue complete.", "dir_queue_complete": "Directory queue complete.",
"fairplay": "Fairplay", "fairplay": "Fairplay",
"finished_song": "Finished song", "finished_track": "Track Finished",
"fp_disabled": "Fair play disabled.", "fp_disabled": "Fair play disabled.",
"fp_enabled": "Fair play enabled.", "fp_enabled": "Fair play enabled.",
"from_position": "From position", "from_position": "From position",
@@ -366,8 +366,8 @@
"no_player": "No active music player.", "no_player": "No active music player.",
"no_search_results": "No search results.", "no_search_results": "No search results.",
"player_queue": "Player queue - Page {0}/{1}", "player_queue": "Player queue - Page {0}/{1}",
"playing_song": "Playing song #{0}", "playing_track": "Playing track #{0}",
"playlists": "`#{0}` - **{1}** by *{2}* ({3} songs)", "playlists": "`#{0}` - **{1}** by *{2}* ({3} tracks)",
"playlists_page": "Page {0} of saved playlists", "playlists_page": "Page {0} of saved playlists",
"playlist_deleted": "Playlist deleted.", "playlist_deleted": "Playlist deleted.",
"playlist_delete_fail": "Failed to delete that playlist. It either doesn't exist, or you are not its author.", "playlist_delete_fail": "Failed to delete that playlist. It either doesn't exist, or you are not its author.",
@@ -375,17 +375,20 @@
"playlist_queue_complete": "Playlist queue complete.", "playlist_queue_complete": "Playlist queue complete.",
"playlist_saved": "Playlist saved", "playlist_saved": "Playlist saved",
"queue": "Queue", "queue": "Queue",
"queued_song": "Queued song", "queued_track": "Queued track",
"queue_cleared": "Music queue cleared.", "queue_cleared": "Music queue cleared.",
"removed_song": "Removed song", "removed_track": "Removed track",
"repeating_none": "Player will stop once the end of queue is reached.", "repeating_none": "Player will stop once the end of queue is reached.",
"repeating_queue": "Player will repeat the queue.", "repeating_queue": "Player will repeat the queue.",
"repeating_track": "Player will keep repeating the same track.", "repeating_track": "Player will keep repeating the same track.",
"set_music_channel": "I will now output playing, finished, paused and removed songs in this channel.", "autoplaying": "Automatically adds related tracks.",
"unset_music_channel": "I will now output playing, finished, paused and removed songs of the newly created music players in the channel music was started from.", "set_music_channel": "I will now output playing, finished, paused and removed tracks in this channel.",
"unset_music_channel": "I will now output playing, finished, paused and removed tracks of the newly created music players in the channel music was started from.",
"current_music_quality": "Currently set music quality is: {0}", "current_music_quality": "Currently set music quality is: {0}",
"music_quality_set": "Music quality has been set to {0}. You will have to destroy and restart music player for the change to take effect.", "music_quality_set": "Music quality has been set to {0}. You will have to destroy and restart music player for the change to take effect.",
"song_moved": "Song moved", "music_autoplay_on": "Music autoplay enabled. I will automatically queue related tracks after each track finishes playing.",
"music_autoplay_off": "Music autoplay disabled.",
"track_moved": "Track moved",
"to_position": "To position", "to_position": "To position",
"volume_input_invalid": "Volume must be between 0 and 100", "volume_input_invalid": "Volume must be between 0 and 100",
"volume_set": "Volume set to {0}%", "volume_set": "Volume set to {0}%",
@@ -731,7 +734,7 @@
"timezone_not_found": "Timezone not found. Use \"timezones\" command to see the list of available timezones.", "timezone_not_found": "Timezone not found. Use \"timezones\" command to see the list of available timezones.",
"timezones_available": "Available Timezones", "timezones_available": "Available Timezones",
"perm_override": "Users will need {0} permission in order to run {1} command.", "perm_override": "Users will need {0} permission in order to run {1} command.",
"song_not_found": "No song found.", "track_not_found": "No track found.",
"define_unknown": "Can't find the definition for that term.", "define_unknown": "Can't find the definition for that term.",
"verbose_errors_enabled": "Incorrectly used commands will now show errors.", "verbose_errors_enabled": "Incorrectly used commands will now show errors.",
"verbose_errors_disabled": "Incorrectly used commands will no longer show errors.", "verbose_errors_disabled": "Incorrectly used commands will no longer show errors.",
@@ -741,7 +744,7 @@
"module": "Module: {0}", "module": "Module: {0}",
"hangman_stopped": "Hangman game stopped.", "hangman_stopped": "Hangman game stopped.",
"queue_stopped": "Player is stopped. Use {0} command to start playing.", "queue_stopped": "Player is stopped. Use {0} command to start playing.",
"removed_song_error": "Song on that index doesn't exist", "removed_track_error": "Track on that index doesn't exist",
"queue_shuffled": "Music queue has been shuffled.", "queue_shuffled": "Music queue has been shuffled.",
"warnings_list": "List of all warned users on the server", "warnings_list": "List of all warned users on the server",
"redacted_too_long": "Redacted because it's too long.", "redacted_too_long": "Redacted because it's too long.",
@@ -873,8 +876,8 @@
"rafflecur_joined": "User {0} joined the raffle", "rafflecur_joined": "User {0} joined the raffle",
"rafflecur_already_joined": "You have already joined this raffle or the value you used is not valid.", "rafflecur_already_joined": "You have already joined this raffle or the value you used is not valid.",
"rafflecur_ended": "{0} raffle ended. {1} won {2}!", "rafflecur_ended": "{0} raffle ended. {1} won {2}!",
"autodc_enable": "I will disconnect from the voice channel when there are no more songs to play.", "autodc_enable": "I will disconnect from the voice channel when there are no more tracks to play.",
"autodc_disable": "I will no longer disconnect from the voice channel when there are no more songs to play.", "autodc_disable": "I will no longer disconnect from the voice channel when there are no more tracks to play.",
"timely_none": "Bot owner didn't specify a timely reward.", "timely_none": "Bot owner didn't specify a timely reward.",
"timely_already_claimed": "You've already claimed your timely reward. You can get it again in {0}.", "timely_already_claimed": "You've already claimed your timely reward. You can get it again in {0}.",
"timely": "You've claimed your {0}. You can claim again in {1}h", "timely": "You've claimed your {0}. You can claim again in {1}h",