mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	fix: Fixed pagination, for real this time, closes #435,
dev: removed some old creds migration code, incremented creds version
This commit is contained in:
		@@ -480,7 +480,8 @@ public partial class Xp : NadekoModule<XpService>
 | 
			
		||||
                          ctx.User.Id,
 | 
			
		||||
                          button,
 | 
			
		||||
                          OnShopUse,
 | 
			
		||||
                          (key, itemType));
 | 
			
		||||
                          (key, itemType),
 | 
			
		||||
                          clearAfter: false);
 | 
			
		||||
 | 
			
		||||
                      return inter;
 | 
			
		||||
                  }
 | 
			
		||||
@@ -494,7 +495,9 @@ public partial class Xp : NadekoModule<XpService>
 | 
			
		||||
                          ctx.User.Id,
 | 
			
		||||
                          button,
 | 
			
		||||
                          OnShopBuy,
 | 
			
		||||
                          (key, itemType));
 | 
			
		||||
                          (key, itemType),
 | 
			
		||||
                          singleUse: true,
 | 
			
		||||
                          clearAfter: false);
 | 
			
		||||
 | 
			
		||||
                      return inter;
 | 
			
		||||
                  }
 | 
			
		||||
@@ -577,6 +580,10 @@ public partial class Xp : NadekoModule<XpService>
 | 
			
		||||
        {
 | 
			
		||||
            await Response().Error(strs.not_enough(_gss.GetCurrencySign())).SendAsync();
 | 
			
		||||
        }
 | 
			
		||||
        else if (result == BuyResult.Success)
 | 
			
		||||
        {
 | 
			
		||||
            await _service.UseShopItemAsync(ctx.User.Id, type, key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private string GetNotifLocationString(XpNotificationLocation loc)
 | 
			
		||||
 
 | 
			
		||||
@@ -133,52 +133,8 @@ public sealed class BotCredsProvider : IBotCredsProvider
 | 
			
		||||
        File.WriteAllText(CREDS_FILE_NAME, ymlData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private string OldCredsJsonPath
 | 
			
		||||
        => Path.Combine(Directory.GetCurrentDirectory(), "credentials.json");
 | 
			
		||||
 | 
			
		||||
    private string OldCredsJsonBackupPath
 | 
			
		||||
        => Path.Combine(Directory.GetCurrentDirectory(), "credentials.json.bak");
 | 
			
		||||
 | 
			
		||||
    private void MigrateCredentials()
 | 
			
		||||
    {
 | 
			
		||||
        if (File.Exists(OldCredsJsonPath))
 | 
			
		||||
        {
 | 
			
		||||
            Log.Information("Migrating old creds...");
 | 
			
		||||
            var jsonCredentialsFileText = File.ReadAllText(OldCredsJsonPath);
 | 
			
		||||
            var oldCreds = JsonConvert.DeserializeObject<OldCreds>(jsonCredentialsFileText);
 | 
			
		||||
 | 
			
		||||
            if (oldCreds is null)
 | 
			
		||||
            {
 | 
			
		||||
                Log.Error("Error while reading old credentials file. Make sure that the file is formatted correctly");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var creds = new Creds
 | 
			
		||||
            {
 | 
			
		||||
                Version = 1,
 | 
			
		||||
                Token = oldCreds.Token,
 | 
			
		||||
                OwnerIds = oldCreds.OwnerIds.Distinct().ToHashSet(),
 | 
			
		||||
                GoogleApiKey = oldCreds.GoogleApiKey,
 | 
			
		||||
                RapidApiKey = oldCreds.MashapeKey,
 | 
			
		||||
                OsuApiKey = oldCreds.OsuApiKey,
 | 
			
		||||
                CleverbotApiKey = oldCreds.CleverbotApiKey,
 | 
			
		||||
                TotalShards = oldCreds.TotalShards <= 1 ? 1 : oldCreds.TotalShards,
 | 
			
		||||
                Patreon = new Creds.PatreonSettings(oldCreds.PatreonAccessToken, null, null, oldCreds.PatreonCampaignId),
 | 
			
		||||
                Votes = new Creds.VotesSettings(oldCreds.VotesUrl, oldCreds.VotesToken, string.Empty, string.Empty),
 | 
			
		||||
                BotListToken = oldCreds.BotListToken,
 | 
			
		||||
                RedisOptions = oldCreds.RedisOptions,
 | 
			
		||||
                LocationIqApiKey = oldCreds.LocationIqApiKey,
 | 
			
		||||
                TimezoneDbApiKey = oldCreds.TimezoneDbApiKey,
 | 
			
		||||
                CoinmarketcapApiKey = oldCreds.CoinmarketcapApiKey
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            File.Move(OldCredsJsonPath, OldCredsJsonBackupPath, true);
 | 
			
		||||
            File.WriteAllText(CredsPath, Yaml.Serializer.Serialize(creds));
 | 
			
		||||
 | 
			
		||||
            Log.Warning(
 | 
			
		||||
                "Data from credentials.json has been moved to creds.yml\nPlease inspect your creds.yml for correctness");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (File.Exists(CREDS_FILE_NAME))
 | 
			
		||||
        {
 | 
			
		||||
            var creds = Yaml.Deserializer.Deserialize<Creds>(File.ReadAllText(CREDS_FILE_NAME));
 | 
			
		||||
@@ -192,9 +148,9 @@ public sealed class BotCredsProvider : IBotCredsProvider
 | 
			
		||||
                File.WriteAllText(CREDS_FILE_NAME, Yaml.Serializer.Serialize(creds));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (creds.Version <= 7)
 | 
			
		||||
            if (creds.Version <= 8)
 | 
			
		||||
            {
 | 
			
		||||
                creds.Version = 8;
 | 
			
		||||
                creds.Version = 9;
 | 
			
		||||
                File.WriteAllText(CREDS_FILE_NAME, Yaml.Serializer.Serialize(creds));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,10 @@ public sealed class Creds : IBotCredentials
 | 
			
		||||
 | 
			
		||||
    [Comment("""
 | 
			
		||||
             Pledge 5$ or more on https://patreon.com/nadekobot and connect your discord account to Patreon.
 | 
			
		||||
             Go to https://dashy.nadeko.bot and login with your discord account
 | 
			
		||||
             Go to https://dashy.nadeko.bot/me and login with your discord account
 | 
			
		||||
             Go to the Keys page and click "Generate New Key" and copy it here
 | 
			
		||||
             You and anyone else with the permission to run `.prompt` command will be able to use natural language to run bot's commands.
 | 
			
		||||
             For example '@Bot how's the weather in Paris' will return the current weather in Paris as if you were to run `.weather Paris` command
 | 
			
		||||
             For example '@Bot how's the weather in Paris' will return the current weather in Paris as if you were to run `.weather Paris` command.
 | 
			
		||||
             """)]
 | 
			
		||||
    public string NadekoAiToken { get; set; }
 | 
			
		||||
    
 | 
			
		||||
@@ -156,7 +156,7 @@ public sealed class Creds : IBotCredentials
 | 
			
		||||
 | 
			
		||||
    public Creds()
 | 
			
		||||
    {
 | 
			
		||||
        Version = 7;
 | 
			
		||||
        Version = 8;
 | 
			
		||||
        Token = string.Empty;
 | 
			
		||||
        UsePrivilegedIntents = true;
 | 
			
		||||
        OwnerIds = new List<ulong>();
 | 
			
		||||
 
 | 
			
		||||
@@ -6,14 +6,16 @@ public interface INadekoInteractionService
 | 
			
		||||
        ulong userId,
 | 
			
		||||
        ButtonBuilder button,
 | 
			
		||||
        Func<SocketMessageComponent, Task> onTrigger,
 | 
			
		||||
        bool singleUse = true);
 | 
			
		||||
        bool singleUse = true,
 | 
			
		||||
        bool clearAfter = true);
 | 
			
		||||
 | 
			
		||||
    public NadekoInteractionBase Create<T>(
 | 
			
		||||
        ulong userId,
 | 
			
		||||
        ButtonBuilder button,
 | 
			
		||||
        Func<SocketMessageComponent, T, Task> onTrigger,
 | 
			
		||||
        in T state,
 | 
			
		||||
        bool singleUse = true);
 | 
			
		||||
        bool singleUse = true,
 | 
			
		||||
        bool clearAfter = true);
 | 
			
		||||
 | 
			
		||||
    NadekoInteractionBase Create(
 | 
			
		||||
        ulong userId,
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,9 @@ public sealed class NadekoButtonInteractionHandler : NadekoInteractionBase
 | 
			
		||||
        ButtonBuilder button,
 | 
			
		||||
        Func<SocketMessageComponent, Task> onAction,
 | 
			
		||||
        bool onlyAuthor,
 | 
			
		||||
        bool singleUse = true)
 | 
			
		||||
        : base(client, authorId, button.CustomId, onAction, onlyAuthor, singleUse)
 | 
			
		||||
        bool singleUse = true,
 | 
			
		||||
        bool clearAfter = true)
 | 
			
		||||
        : base(client, authorId, button.CustomId, onAction, onlyAuthor, singleUse, clearAfter)
 | 
			
		||||
    {
 | 
			
		||||
        Button = button;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ public abstract class NadekoInteractionBase
 | 
			
		||||
    private IUserMessage message = null!;
 | 
			
		||||
    private readonly string _customId;
 | 
			
		||||
    private readonly bool _singleUse;
 | 
			
		||||
    private readonly bool _clearAfter;
 | 
			
		||||
 | 
			
		||||
    public NadekoInteractionBase(
 | 
			
		||||
        DiscordSocketClient client,
 | 
			
		||||
@@ -19,13 +20,16 @@ public abstract class NadekoInteractionBase
 | 
			
		||||
        string customId,
 | 
			
		||||
        Func<SocketMessageComponent, Task> onAction,
 | 
			
		||||
        bool onlyAuthor,
 | 
			
		||||
        bool singleUse = true)
 | 
			
		||||
        bool singleUse = true,
 | 
			
		||||
        bool clearAfter = true)
 | 
			
		||||
    {
 | 
			
		||||
        _authorId = authorId;
 | 
			
		||||
        _customId = customId;
 | 
			
		||||
        _onAction = onAction;
 | 
			
		||||
        _onlyAuthor = onlyAuthor;
 | 
			
		||||
        _singleUse = singleUse;
 | 
			
		||||
        _clearAfter = clearAfter;
 | 
			
		||||
        
 | 
			
		||||
        _interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
 | 
			
		||||
 | 
			
		||||
        Client = client;
 | 
			
		||||
@@ -36,13 +40,11 @@ public abstract class NadekoInteractionBase
 | 
			
		||||
        message = msg;
 | 
			
		||||
 | 
			
		||||
        Client.InteractionCreated += OnInteraction;
 | 
			
		||||
        if (_singleUse)
 | 
			
		||||
            await Task.WhenAny(Task.Delay(30_000), _interactionCompletedSource.Task);
 | 
			
		||||
        else
 | 
			
		||||
            await Task.Delay(30_000);
 | 
			
		||||
        await Task.WhenAny(Task.Delay(30_000), _interactionCompletedSource.Task);
 | 
			
		||||
        Client.InteractionCreated -= OnInteraction;
 | 
			
		||||
 | 
			
		||||
        await msg.ModifyAsync(m => m.Components = new ComponentBuilder().Build());
 | 
			
		||||
        if (_clearAfter)
 | 
			
		||||
            await msg.ModifyAsync(m => m.Components = new ComponentBuilder().Build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Task OnInteraction(SocketInteraction arg)
 | 
			
		||||
@@ -59,11 +61,15 @@ public abstract class NadekoInteractionBase
 | 
			
		||||
        if (smc.Data.CustomId != _customId)
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
        if (_interactionCompletedSource.Task.IsCompleted)
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
        _ = Task.Run(async () =>
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                _interactionCompletedSource.TrySetResult(true);
 | 
			
		||||
                if (_singleUse)
 | 
			
		||||
                    _interactionCompletedSource.TrySetResult(true);
 | 
			
		||||
                await ExecuteOnActionAsync(smc);
 | 
			
		||||
 | 
			
		||||
                if (!smc.HasResponded)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,25 +13,30 @@ public class NadekoInteractionService : INadekoInteractionService, INService
 | 
			
		||||
        ulong userId,
 | 
			
		||||
        ButtonBuilder button,
 | 
			
		||||
        Func<SocketMessageComponent, Task> onTrigger,
 | 
			
		||||
        bool singleUse = true)
 | 
			
		||||
        bool singleUse = true,
 | 
			
		||||
        bool clearAfter = true)
 | 
			
		||||
        => new NadekoButtonInteractionHandler(_client,
 | 
			
		||||
            userId,
 | 
			
		||||
            button,
 | 
			
		||||
            onTrigger,
 | 
			
		||||
            onlyAuthor: true,
 | 
			
		||||
            singleUse: singleUse);
 | 
			
		||||
            singleUse: singleUse,
 | 
			
		||||
            clearAfter: clearAfter);
 | 
			
		||||
 | 
			
		||||
    public NadekoInteractionBase Create<T>(
 | 
			
		||||
        ulong userId,
 | 
			
		||||
        ButtonBuilder button,
 | 
			
		||||
        Func<SocketMessageComponent, T, Task> onTrigger,
 | 
			
		||||
        in T state,
 | 
			
		||||
        bool singleUse = true)
 | 
			
		||||
        bool singleUse = true,
 | 
			
		||||
        bool clearAfter = true
 | 
			
		||||
    )
 | 
			
		||||
        => Create(userId,
 | 
			
		||||
            button,
 | 
			
		||||
            ((Func<T, Func<SocketMessageComponent, Task>>)((data)
 | 
			
		||||
                => smc => onTrigger(smc, data)))(state),
 | 
			
		||||
            singleUse);
 | 
			
		||||
            singleUse,
 | 
			
		||||
            clearAfter);
 | 
			
		||||
 | 
			
		||||
    public NadekoInteractionBase Create(
 | 
			
		||||
        ulong userId,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
namespace NadekoBot.Common;
 | 
			
		||||
 | 
			
		||||
public class OldCreds
 | 
			
		||||
{
 | 
			
		||||
    public string Token { get; set; } = string.Empty;
 | 
			
		||||
    public ulong[] OwnerIds { get; set; } = new ulong[1];
 | 
			
		||||
    public string LoLApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public string GoogleApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public string MashapeKey { get; set; } = string.Empty;
 | 
			
		||||
    public string OsuApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public string CleverbotApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public string CarbonKey { get; set; } = string.Empty;
 | 
			
		||||
    public int TotalShards { get; set; } = 1;
 | 
			
		||||
    public string PatreonAccessToken { get; set; } = string.Empty;
 | 
			
		||||
    public string PatreonCampaignId { get; set; } = "334038";
 | 
			
		||||
    public RestartConfig RestartCommand { get; set; }
 | 
			
		||||
 | 
			
		||||
    public string ShardRunCommand { get; set; } = string.Empty;
 | 
			
		||||
    public string ShardRunArguments { get; set; } = string.Empty;
 | 
			
		||||
    public int? ShardRunPort { get; set; }
 | 
			
		||||
    public string MiningProxyUrl { get; set; } = string.Empty;
 | 
			
		||||
    public string MiningProxyCreds { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
    public string BotListToken { get; set; } = string.Empty;
 | 
			
		||||
    public string TwitchClientId { get; set; } = string.Empty;
 | 
			
		||||
    public string VotesToken { get; set; } = string.Empty;
 | 
			
		||||
    public string VotesUrl { get; set; } = string.Empty;
 | 
			
		||||
    public string RedisOptions { get; set; } = string.Empty;
 | 
			
		||||
    public string LocationIqApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public string TimezoneDbApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public string CoinmarketcapApiKey { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
    public class RestartConfig
 | 
			
		||||
    {
 | 
			
		||||
        public string Cmd { get; set; }
 | 
			
		||||
        public string Args { get; set; }
 | 
			
		||||
 | 
			
		||||
        public RestartConfig(string cmd, string args)
 | 
			
		||||
        {
 | 
			
		||||
            Cmd = cmd;
 | 
			
		||||
            Args = args;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -71,7 +71,8 @@ public partial class ResponseBuilder
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
                    },
 | 
			
		||||
                    true,
 | 
			
		||||
                    singleUse: false);
 | 
			
		||||
                    singleUse: false,
 | 
			
		||||
                    clearAfter: false);
 | 
			
		||||
 | 
			
		||||
                if (_paginationBuilder.InteractionFunc is not null)
 | 
			
		||||
                {
 | 
			
		||||
@@ -106,7 +107,8 @@ public partial class ResponseBuilder
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
                    },
 | 
			
		||||
                    true,
 | 
			
		||||
                    singleUse: false);
 | 
			
		||||
                    singleUse: false,
 | 
			
		||||
                    clearAfter: false);
 | 
			
		||||
 | 
			
		||||
                return (leftBtnInter, maybeInter, rightBtnInter);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user