mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 01:38:27 -04:00
Make extensive use of raw string literals C#11 feature
This commit is contained in:
@@ -19,19 +19,21 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
||||
private const string MENTION_PH = "%bot.mention%";
|
||||
|
||||
private const string PREPEND_EXPORT =
|
||||
@"# Keys are triggers, Each key has a LIST of expressions in the following format:
|
||||
# - res: Response string
|
||||
# id: Alphanumeric id used for commands related to the expression. (Note, when using .exprsimport, a new id will be generated.)
|
||||
# react:
|
||||
# - <List
|
||||
# - of
|
||||
# - reactions>
|
||||
# at: Whether expression allows targets (see .h .exprat)
|
||||
# ca: Whether expression expects trigger anywhere (see .h .exprca)
|
||||
# dm: Whether expression DMs the response (see .h .exprdm)
|
||||
# ad: Whether expression automatically deletes triggering message (see .h .exprad)
|
||||
"""
|
||||
# Keys are triggers, Each key has a LIST of expressions in the following format:
|
||||
# - res: Response string
|
||||
# id: Alphanumeric id used for commands related to the expression. (Note, when using .exprsimport, a new id will be generated.)
|
||||
# react:
|
||||
# - <List
|
||||
# - of
|
||||
# - reactions>
|
||||
# at: Whether expression allows targets (see .h .exprat)
|
||||
# ca: Whether expression expects trigger anywhere (see .h .exprca)
|
||||
# dm: Whether expression DMs the response (see .h .exprdm)
|
||||
# ad: Whether expression automatically deletes triggering message (see .h .exprad)
|
||||
|
||||
|
||||
";
|
||||
""";
|
||||
|
||||
private static readonly ISerializer _exportSerializer = new SerializerBuilder()
|
||||
.WithEventEmitter(args
|
||||
|
@@ -10,50 +10,58 @@ namespace NadekoBot.Modules.Gambling.Common;
|
||||
[Cloneable]
|
||||
public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
[Comment("""DO NOT CHANGE""")]
|
||||
public int Version { get; set; } = 2;
|
||||
|
||||
[Comment(@"Currency settings")]
|
||||
[Comment("""Currency settings""")]
|
||||
public CurrencyConfig Currency { get; set; }
|
||||
|
||||
[Comment(@"Minimum amount users can bet (>=0)")]
|
||||
[Comment("""Minimum amount users can bet (>=0)""")]
|
||||
public int MinBet { get; set; } = 0;
|
||||
|
||||
[Comment(@"Maximum amount users can bet
|
||||
Set 0 for unlimited")]
|
||||
[Comment("""
|
||||
Maximum amount users can bet
|
||||
Set 0 for unlimited
|
||||
""")]
|
||||
public int MaxBet { get; set; } = 0;
|
||||
|
||||
[Comment(@"Settings for betflip command")]
|
||||
[Comment("""Settings for betflip command""")]
|
||||
public BetFlipConfig BetFlip { get; set; }
|
||||
|
||||
[Comment(@"Settings for betroll command")]
|
||||
[Comment("""Settings for betroll command""")]
|
||||
public BetRollConfig BetRoll { get; set; }
|
||||
|
||||
[Comment(@"Automatic currency generation settings.")]
|
||||
[Comment("""Automatic currency generation settings.""")]
|
||||
public GenerationConfig Generation { get; set; }
|
||||
|
||||
[Comment(@"Settings for timely command
|
||||
(letting people claim X amount of currency every Y hours)")]
|
||||
[Comment("""
|
||||
Settings for timely command
|
||||
(letting people claim X amount of currency every Y hours)
|
||||
""")]
|
||||
public TimelyConfig Timely { get; set; }
|
||||
|
||||
[Comment(@"How much will each user's owned currency decay over time.")]
|
||||
[Comment("""How much will each user's owned currency decay over time.""")]
|
||||
public DecayConfig Decay { get; set; }
|
||||
|
||||
[Comment(@"Settings for LuckyLadder command")]
|
||||
[Comment("""Settings for LuckyLadder command""")]
|
||||
public LuckyLadderSettings LuckyLadder { get; set; }
|
||||
|
||||
[Comment(@"Settings related to waifus")]
|
||||
[Comment("""Settings related to waifus""")]
|
||||
public WaifuConfig Waifu { get; set; }
|
||||
|
||||
[Comment(@"Amount of currency selfhosters will get PER pledged dollar CENT.
|
||||
1 = 100 currency per $. Used almost exclusively on public nadeko.")]
|
||||
[Comment("""
|
||||
Amount of currency selfhosters will get PER pledged dollar CENT.
|
||||
1 = 100 currency per $. Used almost exclusively on public nadeko.
|
||||
""")]
|
||||
public decimal PatreonCurrencyPerCent { get; set; } = 1;
|
||||
|
||||
[Comment(@"Currency reward per vote.
|
||||
This will work only if you've set up VotesApi and correct credentials for topgg and/or discords voting")]
|
||||
[Comment("""
|
||||
Currency reward per vote.
|
||||
This will work only if you've set up VotesApi and correct credentials for topgg and/or discords voting
|
||||
""")]
|
||||
public long VoteReward { get; set; } = 100;
|
||||
|
||||
[Comment(@"Slot config")]
|
||||
[Comment("""Slot config""")]
|
||||
public SlotsConfig Slots { get; set; }
|
||||
|
||||
public GamblingConfig()
|
||||
@@ -72,42 +80,50 @@ This will work only if you've set up VotesApi and correct credentials for topgg
|
||||
|
||||
public class CurrencyConfig
|
||||
{
|
||||
[Comment(@"What is the emoji/character which represents the currency")]
|
||||
[Comment("""What is the emoji/character which represents the currency""")]
|
||||
public string Sign { get; set; } = "🌸";
|
||||
|
||||
[Comment(@"What is the name of the currency")]
|
||||
[Comment("""What is the name of the currency""")]
|
||||
public string Name { get; set; } = "Nadeko Flower";
|
||||
|
||||
[Comment(@"For how long (in days) will the transactions be kept in the database (curtrs)
|
||||
Set 0 to disable cleanup (keep transactions forever)")]
|
||||
[Comment("""
|
||||
For how long (in days) will the transactions be kept in the database (curtrs)
|
||||
Set 0 to disable cleanup (keep transactions forever)
|
||||
""")]
|
||||
public int TransactionsLifetime { get; set; } = 0;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public partial class TimelyConfig
|
||||
{
|
||||
[Comment(@"How much currency will the users get every time they run .timely command
|
||||
setting to 0 or less will disable this feature")]
|
||||
[Comment("""
|
||||
How much currency will the users get every time they run .timely command
|
||||
setting to 0 or less will disable this feature
|
||||
""")]
|
||||
public int Amount { get; set; } = 0;
|
||||
|
||||
[Comment(@"How often (in hours) can users claim currency with .timely command
|
||||
setting to 0 or less will disable this feature")]
|
||||
[Comment("""
|
||||
How often (in hours) can users claim currency with .timely command
|
||||
setting to 0 or less will disable this feature
|
||||
""")]
|
||||
public int Cooldown { get; set; } = 24;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public partial class BetFlipConfig
|
||||
{
|
||||
[Comment(@"Bet multiplier if user guesses correctly")]
|
||||
[Comment("""Bet multiplier if user guesses correctly""")]
|
||||
public decimal Multiplier { get; set; } = 1.95M;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public partial class BetRollConfig
|
||||
{
|
||||
[Comment(@"When betroll is played, user will roll a number 0-100.
|
||||
This setting will describe which multiplier is used for when the roll is higher than the given number.
|
||||
Doesn't have to be ordered.")]
|
||||
[Comment("""
|
||||
When betroll is played, user will roll a number 0-100.
|
||||
This setting will describe which multiplier is used for when the roll is higher than the given number.
|
||||
Doesn't have to be ordered.
|
||||
""")]
|
||||
public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>();
|
||||
|
||||
public BetRollConfig()
|
||||
@@ -134,48 +150,56 @@ Doesn't have to be ordered.")]
|
||||
[Cloneable]
|
||||
public partial class GenerationConfig
|
||||
{
|
||||
[Comment(@"when currency is generated, should it also have a random password
|
||||
associated with it which users have to type after the .pick command
|
||||
in order to get it")]
|
||||
[Comment("""
|
||||
when currency is generated, should it also have a random password
|
||||
associated with it which users have to type after the .pick command
|
||||
in order to get it
|
||||
""")]
|
||||
public bool HasPassword { get; set; } = true;
|
||||
|
||||
[Comment(@"Every message sent has a certain % chance to generate the currency
|
||||
specify the percentage here (1 being 100%, 0 being 0% - for example
|
||||
default is 0.02, which is 2%")]
|
||||
[Comment("""
|
||||
Every message sent has a certain % chance to generate the currency
|
||||
specify the percentage here (1 being 100%, 0 being 0% - for example
|
||||
default is 0.02, which is 2%
|
||||
""")]
|
||||
public decimal Chance { get; set; } = 0.02M;
|
||||
|
||||
[Comment(@"How many seconds have to pass for the next message to have a chance to spawn currency")]
|
||||
[Comment("""How many seconds have to pass for the next message to have a chance to spawn currency""")]
|
||||
public int GenCooldown { get; set; } = 10;
|
||||
|
||||
[Comment(@"Minimum amount of currency that can spawn")]
|
||||
[Comment("""Minimum amount of currency that can spawn""")]
|
||||
public int MinAmount { get; set; } = 1;
|
||||
|
||||
[Comment(@"Maximum amount of currency that can spawn.
|
||||
Set to the same value as MinAmount to always spawn the same amount")]
|
||||
[Comment("""
|
||||
Maximum amount of currency that can spawn.
|
||||
Set to the same value as MinAmount to always spawn the same amount
|
||||
""")]
|
||||
public int MaxAmount { get; set; } = 1;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public partial class DecayConfig
|
||||
{
|
||||
[Comment(@"Percentage of user's current currency which will be deducted every 24h.
|
||||
0 - 1 (1 is 100%, 0.5 50%, 0 disabled)")]
|
||||
[Comment("""
|
||||
Percentage of user's current currency which will be deducted every 24h.
|
||||
0 - 1 (1 is 100%, 0.5 50%, 0 disabled)
|
||||
""")]
|
||||
public decimal Percent { get; set; } = 0;
|
||||
|
||||
[Comment(@"Maximum amount of user's currency that can decay at each interval. 0 for unlimited.")]
|
||||
[Comment("""Maximum amount of user's currency that can decay at each interval. 0 for unlimited.""")]
|
||||
public int MaxDecay { get; set; } = 0;
|
||||
|
||||
[Comment(@"Only users who have more than this amount will have their currency decay.")]
|
||||
[Comment("""Only users who have more than this amount will have their currency decay.""")]
|
||||
public int MinThreshold { get; set; } = 99;
|
||||
|
||||
[Comment(@"How often, in hours, does the decay run. Default is 24 hours")]
|
||||
[Comment("""How often, in hours, does the decay run. Default is 24 hours""")]
|
||||
public int HourInterval { get; set; } = 24;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public partial class LuckyLadderSettings
|
||||
{
|
||||
[Comment(@"Self-Explanatory. Has to have 8 values, otherwise the command won't work.")]
|
||||
[Comment("""Self-Explanatory. Has to have 8 values, otherwise the command won't work.""")]
|
||||
public decimal[] Multipliers { get; set; }
|
||||
|
||||
public LuckyLadderSettings()
|
||||
@@ -185,17 +209,21 @@ public partial class LuckyLadderSettings
|
||||
[Cloneable]
|
||||
public sealed partial class WaifuConfig
|
||||
{
|
||||
[Comment(@"Minimum price a waifu can have")]
|
||||
[Comment("""Minimum price a waifu can have""")]
|
||||
public long MinPrice { get; set; } = 50;
|
||||
|
||||
public MultipliersData Multipliers { get; set; } = new();
|
||||
|
||||
[Comment(@"Settings for periodic waifu price decay.
|
||||
Waifu price decays only if the waifu has no claimer.")]
|
||||
[Comment("""
|
||||
Settings for periodic waifu price decay.
|
||||
Waifu price decays only if the waifu has no claimer.
|
||||
""")]
|
||||
public WaifuDecayConfig Decay { get; set; } = new();
|
||||
|
||||
[Comment(@"List of items available for gifting.
|
||||
If negative is true, gift will instead reduce waifu value.")]
|
||||
[Comment("""
|
||||
List of items available for gifting.
|
||||
If negative is true, gift will instead reduce waifu value.
|
||||
""")]
|
||||
public List<WaifuItemModel> Items { get; set; } = new();
|
||||
|
||||
public WaifuConfig()
|
||||
@@ -241,16 +269,20 @@ If negative is true, gift will instead reduce waifu value.")]
|
||||
|
||||
public class WaifuDecayConfig
|
||||
{
|
||||
[Comment(@"Percentage (0 - 100) of the waifu value to reduce.
|
||||
Set 0 to disable
|
||||
For example if a waifu has a price of 500$, setting this value to 10 would reduce the waifu value by 10% (50$)")]
|
||||
[Comment("""
|
||||
Percentage (0 - 100) of the waifu value to reduce.
|
||||
Set 0 to disable
|
||||
For example if a waifu has a price of 500$, setting this value to 10 would reduce the waifu value by 10% (50$)
|
||||
""")]
|
||||
public int Percent { get; set; } = 0;
|
||||
|
||||
[Comment(@"How often to decay waifu values, in hours")]
|
||||
[Comment("""How often to decay waifu values, in hours""")]
|
||||
public int HourInterval { get; set; } = 24;
|
||||
|
||||
[Comment(@"Minimum waifu price required for the decay to be applied.
|
||||
For example if this value is set to 300, any waifu with the price 300 or less will not experience decay.")]
|
||||
[Comment("""
|
||||
Minimum waifu price required for the decay to be applied.
|
||||
For example if this value is set to 300, any waifu with the price 300 or less will not experience decay.
|
||||
""")]
|
||||
public long MinPrice { get; set; } = 300;
|
||||
}
|
||||
}
|
||||
@@ -258,47 +290,61 @@ For example if this value is set to 300, any waifu with the price 300 or less wi
|
||||
[Cloneable]
|
||||
public sealed partial class MultipliersData
|
||||
{
|
||||
[Comment(@"Multiplier for waifureset. Default 150.
|
||||
Formula (at the time of writing this):
|
||||
price = (waifu_price * 1.25f) + ((number_of_divorces + changes_of_heart + 2) * WaifuReset) rounded up")]
|
||||
[Comment("""
|
||||
Multiplier for waifureset. Default 150.
|
||||
Formula (at the time of writing this):
|
||||
price = (waifu_price * 1.25f) + ((number_of_divorces + changes_of_heart + 2) * WaifuReset) rounded up
|
||||
""")]
|
||||
public int WaifuReset { get; set; } = 150;
|
||||
|
||||
[Comment(@"The minimum amount of currency that you have to pay
|
||||
in order to buy a waifu who doesn't have a crush on you.
|
||||
Default is 1.1
|
||||
Example: If a waifu is worth 100, you will have to pay at least 100 * NormalClaim currency to claim her.
|
||||
(100 * 1.1 = 110)")]
|
||||
[Comment("""
|
||||
The minimum amount of currency that you have to pay
|
||||
in order to buy a waifu who doesn't have a crush on you.
|
||||
Default is 1.1
|
||||
Example: If a waifu is worth 100, you will have to pay at least 100 * NormalClaim currency to claim her.
|
||||
(100 * 1.1 = 110)
|
||||
""")]
|
||||
public decimal NormalClaim { get; set; } = 1.1m;
|
||||
|
||||
[Comment(@"The minimum amount of currency that you have to pay
|
||||
in order to buy a waifu that has a crush on you.
|
||||
Default is 0.88
|
||||
Example: If a waifu is worth 100, you will have to pay at least 100 * CrushClaim currency to claim her.
|
||||
(100 * 0.88 = 88)")]
|
||||
[Comment("""
|
||||
The minimum amount of currency that you have to pay
|
||||
in order to buy a waifu that has a crush on you.
|
||||
Default is 0.88
|
||||
Example: If a waifu is worth 100, you will have to pay at least 100 * CrushClaim currency to claim her.
|
||||
(100 * 0.88 = 88)
|
||||
""")]
|
||||
public decimal CrushClaim { get; set; } = 0.88M;
|
||||
|
||||
[Comment(@"When divorcing a waifu, her new value will be her current value multiplied by this number.
|
||||
Default 0.75 (meaning will lose 25% of her value)")]
|
||||
[Comment("""
|
||||
When divorcing a waifu, her new value will be her current value multiplied by this number.
|
||||
Default 0.75 (meaning will lose 25% of her value)
|
||||
""")]
|
||||
public decimal DivorceNewValue { get; set; } = 0.75M;
|
||||
|
||||
[Comment(@"All gift prices will be multiplied by this number.
|
||||
Default 1 (meaning no effect)")]
|
||||
[Comment("""
|
||||
All gift prices will be multiplied by this number.
|
||||
Default 1 (meaning no effect)
|
||||
""")]
|
||||
public decimal AllGiftPrices { get; set; } = 1.0M;
|
||||
|
||||
[Comment(@"What percentage of the value of the gift will a waifu gain when she's gifted.
|
||||
Default 0.95 (meaning 95%)
|
||||
Example: If a waifu is worth 1000, and she receives a gift worth 100, her new value will be 1095)")]
|
||||
[Comment("""
|
||||
What percentage of the value of the gift will a waifu gain when she's gifted.
|
||||
Default 0.95 (meaning 95%)
|
||||
Example: If a waifu is worth 1000, and she receives a gift worth 100, her new value will be 1095)
|
||||
""")]
|
||||
public decimal GiftEffect { get; set; } = 0.95M;
|
||||
|
||||
[Comment(@"What percentage of the value of the gift will a waifu lose when she's gifted a gift marked as 'negative'.
|
||||
Default 0.5 (meaning 50%)
|
||||
Example: If a waifu is worth 1000, and she receives a negative gift worth 100, her new value will be 950)")]
|
||||
[Comment("""
|
||||
What percentage of the value of the gift will a waifu lose when she's gifted a gift marked as 'negative'.
|
||||
Default 0.5 (meaning 50%)
|
||||
Example: If a waifu is worth 1000, and she receives a negative gift worth 100, her new value will be 950)
|
||||
""")]
|
||||
public decimal NegativeGiftEffect { get; set; } = 0.50M;
|
||||
}
|
||||
|
||||
public sealed class SlotsConfig
|
||||
{
|
||||
[Comment(@"Hex value of the color which the numbers on the slot image will have.")]
|
||||
[Comment("""Hex value of the color which the numbers on the slot image will have.""")]
|
||||
public Rgba32 CurrencyFontColor { get; set; } = Color.Red;
|
||||
}
|
||||
|
||||
|
@@ -96,9 +96,12 @@ public class GamblingService : INService, IReadyExecutor
|
||||
continue;
|
||||
}
|
||||
|
||||
Log.Information(@"Decaying users' currency - decay: {ConfigDecayPercent}%
|
||||
| max: {MaxDecay}
|
||||
| threshold: {DecayMinTreshold}",
|
||||
Log.Information("""
|
||||
--- Decaying users' currency ---
|
||||
| decay: {ConfigDecayPercent}%
|
||||
| max: {MaxDecay}
|
||||
| threshold: {DecayMinTreshold}
|
||||
""",
|
||||
config.Decay.Percent * 100,
|
||||
maxDecay,
|
||||
config.Decay.MinThreshold);
|
||||
|
@@ -187,11 +187,13 @@ public class ChatterBotService : IExecOnMessage
|
||||
// , footer: counter > 0 ? counter.ToString() : null
|
||||
);
|
||||
|
||||
Log.Information(@"CleverBot Executed
|
||||
Server: {GuildName} [{GuildId}]
|
||||
Channel: {ChannelName} [{ChannelId}]
|
||||
UserId: {Author} [{AuthorId}]
|
||||
Message: {Content}",
|
||||
Log.Information("""
|
||||
CleverBot Executed
|
||||
Server: {GuildName} [{GuildId}]
|
||||
Channel: {ChannelName} [{ChannelId}]
|
||||
UserId: {Author} [{AuthorId}]
|
||||
Message: {Content}
|
||||
""",
|
||||
guild.Name,
|
||||
guild.Id,
|
||||
usrMsg.Channel?.Name,
|
||||
|
@@ -110,8 +110,10 @@ public sealed partial class TriviaConfig
|
||||
[Comment("The amount of currency awarded to the winner of the trivia game.")]
|
||||
public long CurrencyReward { get; set; }
|
||||
|
||||
[Comment(@"Users won't be able to start trivia games which have
|
||||
a smaller win requirement than the one specified by this setting.")]
|
||||
[Comment("""
|
||||
Users won't be able to start trivia games which have
|
||||
a smaller win requirement than the one specified by this setting.
|
||||
""")]
|
||||
public int MinimumWinReq { get; set; } = 1;
|
||||
}
|
||||
|
||||
|
@@ -14,13 +14,15 @@ public partial class Games
|
||||
=> await SendConfirmAsync(GetText(strs.hangman_types(prefix)), _service.GetHangmanTypes().Join('\n'));
|
||||
|
||||
private static string Draw(HangmanGame.State state)
|
||||
=> $@". ┌─────┐
|
||||
.┃...............┋
|
||||
.┃...............┋
|
||||
.┃{(state.Errors > 0 ? ".............😲" : "")}
|
||||
.┃{(state.Errors > 1 ? "............./" : "")} {(state.Errors > 2 ? "|" : "")} {(state.Errors > 3 ? "\\" : "")}
|
||||
.┃{(state.Errors > 4 ? "............../" : "")} {(state.Errors > 5 ? "\\" : "")}
|
||||
/-\";
|
||||
=> $"""
|
||||
. ┌─────┐
|
||||
.┃...............┋
|
||||
.┃...............┋
|
||||
.┃{(state.Errors > 0 ? ".............😲" : "")}
|
||||
.┃{(state.Errors > 1 ? "............./" : "")} {(state.Errors > 2 ? "|" : "")} {(state.Errors > 3 ? "\\" : "")}
|
||||
.┃{(state.Errors > 4 ? "............../" : "")} {(state.Errors > 5 ? "\\" : "")}
|
||||
/-\
|
||||
""";
|
||||
|
||||
public static IEmbedBuilder GetEmbed(IEmbedBuilderService eb, HangmanGame.State state)
|
||||
{
|
||||
|
@@ -69,7 +69,7 @@ public class TypingGame
|
||||
try
|
||||
{
|
||||
await Channel.SendConfirmAsync(_eb,
|
||||
$@":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.");
|
||||
$":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.");
|
||||
|
||||
|
||||
var time = _options.StartTime;
|
||||
|
@@ -78,13 +78,13 @@ public class TriviaQuestion
|
||||
private static string Clean(string str)
|
||||
{
|
||||
str = " " + str.ToLowerInvariant() + " ";
|
||||
str = Regex.Replace(str, "\\s+", " ");
|
||||
str = Regex.Replace(str, "[^\\w\\d\\s]", "");
|
||||
str = Regex.Replace(str, @"\s+", " ");
|
||||
str = Regex.Replace(str, @"[^\w\d\s]", "");
|
||||
//Here's where custom modification can be done
|
||||
str = Regex.Replace(str, "\\s(a|an|the|of|in|for|to|as|at|be)\\s", " ");
|
||||
str = Regex.Replace(str, @"\s(a|an|the|of|in|for|to|as|at|be)\s", " ");
|
||||
//End custom mod and cleanup whitespace
|
||||
str = Regex.Replace(str, "^\\s+", "");
|
||||
str = Regex.Replace(str, "\\s+$", "");
|
||||
str = Regex.Replace(str, @"^\s+", "");
|
||||
str = Regex.Replace(str, @"\s+$", "");
|
||||
//Trim the really long answers
|
||||
str = str.Length <= MAX_STRING_LENGTH ? str : str[..MAX_STRING_LENGTH];
|
||||
return str;
|
||||
|
@@ -490,13 +490,15 @@ public partial class Help : NadekoModule<HelpService>
|
||||
|
||||
private Task SelfhostAction(SocketMessageComponent smc, object _)
|
||||
=> smc.RespondConfirmAsync(_eb,
|
||||
@"- In case you don't want or cannot Donate to NadekoBot project, but you
|
||||
- NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own ""selfhosted"" instance on your computer or server for free.
|
||||
|
||||
*Keep in mind that running the bot on your computer means that the bot will be offline when you turn off your computer*
|
||||
|
||||
- You can find the selfhosting guides by using the `.guide` command and clicking on the second link that pops up.
|
||||
- If you decide to selfhost the bot, still consider [supporting the project](https://patreon.com/join/nadekobot) to keep the development going :)",
|
||||
"""
|
||||
- In case you don't want or cannot Donate to NadekoBot project, but you
|
||||
- NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own "selfhosted" instance on your computer or server for free.
|
||||
|
||||
*Keep in mind that running the bot on your computer means that the bot will be offline when you turn off your computer*
|
||||
|
||||
- You can find the selfhosting guides by using the `.guide` command and clicking on the second link that pops up.
|
||||
- If you decide to selfhost the bot, still consider [supporting the project](https://patreon.com/join/nadekobot) to keep the development going :)
|
||||
""",
|
||||
true);
|
||||
|
||||
[Cmd]
|
||||
@@ -541,12 +543,14 @@ Nadeko will DM you the welcome instructions, and you may start using the patron-
|
||||
🎉 **Enjoy!** 🎉
|
||||
")
|
||||
.AddField("Troubleshooting",
|
||||
@"
|
||||
*In case you didn't receive the rewards within 5 minutes:*
|
||||
`1.` Make sure your DMs are open to everyone. Maybe your pledge was processed successfully but the bot was unable to DM you. Use the `.patron` command to check your status.
|
||||
`2.` Make sure you've connected the CORRECT Discord account. Quite often users log in to different Discord accounts in their browser. You may also try disconnecting and reconnecting your account.
|
||||
`3.` Make sure your payment has been processed and not declined by Patreon.
|
||||
`4.` If any of the previous steps don't help, you can join the nadeko support server <https://discord.nadeko.bot> and ask for help in the #help channel");
|
||||
"""
|
||||
|
||||
*In case you didn't receive the rewards within 5 minutes:*
|
||||
`1.` Make sure your DMs are open to everyone. Maybe your pledge was processed successfully but the bot was unable to DM you. Use the `.patron` command to check your status.
|
||||
`2.` Make sure you've connected the CORRECT Discord account. Quite often users log in to different Discord accounts in their browser. You may also try disconnecting and reconnecting your account.
|
||||
`3.` Make sure your payment has been processed and not declined by Patreon.
|
||||
`4.` If any of the previous steps don't help, you can join the nadeko support server <https://discord.nadeko.bot> and ask for help in the #help channel
|
||||
""");
|
||||
|
||||
try
|
||||
{
|
||||
|
@@ -39,9 +39,9 @@ public static class MusicExtensions
|
||||
if (trackInfo.Duration == TimeSpan.MaxValue)
|
||||
return "∞";
|
||||
if (trackInfo.Duration.TotalHours >= 1)
|
||||
return trackInfo.Duration.ToString(@"hh\:mm\:ss");
|
||||
return trackInfo.Duration.ToString("""hh\:mm\:ss""");
|
||||
|
||||
return trackInfo.Duration.ToString(@"mm\:ss");
|
||||
return trackInfo.Duration.ToString("""mm\:ss""");
|
||||
}
|
||||
|
||||
public static ICachableTrackData ToCachedData(this ITrackInfo trackInfo, string id)
|
||||
|
@@ -5,10 +5,10 @@ namespace NadekoBot.Modules.Music.Resolvers;
|
||||
|
||||
public class RadioResolver : IRadioResolver
|
||||
{
|
||||
private readonly Regex _plsRegex = new("File1=(?<url>.*?)\\n", RegexOptions.Compiled);
|
||||
private readonly Regex _m3URegex = new("(?<url>^[^#].*)", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
private readonly Regex _asxRegex = new("<ref href=\"(?<url>.*?)\"", RegexOptions.Compiled);
|
||||
private readonly Regex _xspfRegex = new("<location>(?<url>.*?)</location>", RegexOptions.Compiled);
|
||||
private readonly Regex _plsRegex = new(@"File1=(?<url>.*?)\n", RegexOptions.Compiled);
|
||||
private readonly Regex _m3URegex = new(@"(?<url>^[^#].*)", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
private readonly Regex _asxRegex = new(@"<ref href=""(?<url>.*?)""", RegexOptions.Compiled);
|
||||
private readonly Regex _xspfRegex = new(@"<location>(?<url>.*?)</location>", RegexOptions.Compiled);
|
||||
|
||||
public async Task<ITrackInfo> ResolveByQueryAsync(string query)
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ public partial class Searches
|
||||
|
||||
var channelId = m.Groups["channelid"].Value;
|
||||
|
||||
return Feed("https://www.youtube.com/feeds/videos.xml?channel_id=" + channelId, channel, message);
|
||||
return Feed($"https://www.youtube.com/feeds/videos.xml?channel_id={channelId}", channel, message);
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
|
@@ -304,7 +304,7 @@ public partial class Searches
|
||||
|
||||
private static string ShortLeagueName(string str)
|
||||
{
|
||||
var league = Regex.Replace(str, "Hardcore", "HC", RegexOptions.IgnoreCase);
|
||||
var league = str.Replace("Hardcore", "HC", StringComparison.InvariantCultureIgnoreCase);
|
||||
|
||||
return league;
|
||||
}
|
||||
|
@@ -9,51 +9,61 @@ public partial class SearchesConfig : ICloneable<SearchesConfig>
|
||||
[Comment("DO NOT CHANGE")]
|
||||
public int Version { get; set; } = 0;
|
||||
|
||||
[Comment(@"Which engine should .search command
|
||||
'google_scrape' - default. Scrapes the webpage for results. May break. Requires no api keys.
|
||||
'google' - official google api. Requires googleApiKey and google.searchId set in creds.yml
|
||||
'searx' - requires at least one searx instance specified in the 'searxInstances' property below")]
|
||||
[Comment("""
|
||||
Which engine should .search command
|
||||
'google_scrape' - default. Scrapes the webpage for results. May break. Requires no api keys.
|
||||
'google' - official google api. Requires googleApiKey and google.searchId set in creds.yml
|
||||
'searx' - requires at least one searx instance specified in the 'searxInstances' property below
|
||||
""")]
|
||||
public WebSearchEngine WebSearchEngine { get; set; } = WebSearchEngine.Google_Scrape;
|
||||
|
||||
[Comment(@"Which engine should .image command use
|
||||
'google'- official google api. googleApiKey and google.imageSearchId set in creds.yml
|
||||
'searx' requires at least one searx instance specified in the 'searxInstances' property below")]
|
||||
[Comment("""
|
||||
Which engine should .image command use
|
||||
'google'- official google api. googleApiKey and google.imageSearchId set in creds.yml
|
||||
'searx' requires at least one searx instance specified in the 'searxInstances' property below
|
||||
""")]
|
||||
public ImgSearchEngine ImgSearchEngine { get; set; } = ImgSearchEngine.Google;
|
||||
|
||||
|
||||
[Comment(@"Which search provider will be used for the `.youtube` command.
|
||||
|
||||
- `ytDataApiv3` - uses google's official youtube data api. Requires `GoogleApiKey` set in creds and youtube data api enabled in developers console
|
||||
|
||||
- `ytdl` - default, uses youtube-dl. Requires `youtube-dl` to be installed and it's path added to env variables. Slow.
|
||||
|
||||
- `ytdlp` - recommended easy, uses `yt-dlp`. Requires `yt-dlp` to be installed and it's path added to env variables
|
||||
|
||||
- `invidious` - recommended advanced, uses invidious api. Requires at least one invidious instance specified in the `invidiousInstances` property")]
|
||||
[Comment("""
|
||||
Which search provider will be used for the `.youtube` command.
|
||||
|
||||
- `ytDataApiv3` - uses google's official youtube data api. Requires `GoogleApiKey` set in creds and youtube data api enabled in developers console
|
||||
|
||||
- `ytdl` - default, uses youtube-dl. Requires `youtube-dl` to be installed and it's path added to env variables. Slow.
|
||||
|
||||
- `ytdlp` - recommended easy, uses `yt-dlp`. Requires `yt-dlp` to be installed and it's path added to env variables
|
||||
|
||||
- `invidious` - recommended advanced, uses invidious api. Requires at least one invidious instance specified in the `invidiousInstances` property
|
||||
""")]
|
||||
public YoutubeSearcher YtProvider { get; set; } = YoutubeSearcher.Ytdl;
|
||||
|
||||
[Comment(@"Set the searx instance urls in case you want to use 'searx' for either img or web search.
|
||||
Nadeko will use a random one for each request.
|
||||
Use a fully qualified url. Example: `https://my-searx-instance.mydomain.com`
|
||||
Instances specified must support 'format=json' query parameter.
|
||||
- In case you're running your own searx instance, set
|
||||
|
||||
search:
|
||||
formats:
|
||||
- json
|
||||
|
||||
in 'searxng/settings.yml' on your server
|
||||
|
||||
- If you're using a public instance, make sure that the instance you're using supports it (they usually don't)")]
|
||||
[Comment("""
|
||||
Set the searx instance urls in case you want to use 'searx' for either img or web search.
|
||||
Nadeko will use a random one for each request.
|
||||
Use a fully qualified url. Example: `https://my-searx-instance.mydomain.com`
|
||||
Instances specified must support 'format=json' query parameter.
|
||||
- In case you're running your own searx instance, set
|
||||
|
||||
search:
|
||||
formats:
|
||||
- json
|
||||
|
||||
in 'searxng/settings.yml' on your server
|
||||
|
||||
- If you're using a public instance, make sure that the instance you're using supports it (they usually don't)
|
||||
""")]
|
||||
public List<string> SearxInstances { get; set; } = new List<string>();
|
||||
|
||||
[Comment(@"Set the invidious instance urls in case you want to use 'invidious' for `.youtube` search
|
||||
Nadeko will use a random one for each request.
|
||||
These instances may be used for music queue functionality in the future.
|
||||
Use a fully qualified url. Example: https://my-invidious-instance.mydomain.com
|
||||
|
||||
Instances specified must have api available.
|
||||
You check that by opening an api endpoint in your browser. For example: https://my-invidious-instance.mydomain.com/api/v1/trending")]
|
||||
[Comment("""
|
||||
Set the invidious instance urls in case you want to use 'invidious' for `.youtube` search
|
||||
Nadeko will use a random one for each request.
|
||||
These instances may be used for music queue functionality in the future.
|
||||
Use a fully qualified url. Example: https://my-invidious-instance.mydomain.com
|
||||
|
||||
Instances specified must have api available.
|
||||
You check that by opening an api endpoint in your browser. For example: https://my-invidious-instance.mydomain.com/api/v1/trending
|
||||
""")]
|
||||
public List<string> InvidiousInstances { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
|
@@ -23,8 +23,10 @@ public class TrovoProvider : Provider
|
||||
|
||||
if (string.IsNullOrWhiteSpace(creds.GetCreds().TrovoClientId))
|
||||
{
|
||||
Log.Warning(@"Trovo streams are using a default clientId.
|
||||
If you are experiencing ratelimits, you should create your own application at: https://developer.trovo.live/");
|
||||
Log.Warning("""
|
||||
Trovo streams are using a default clientId.
|
||||
If you are experiencing ratelimits, you should create your own application at: https://developer.trovo.live/
|
||||
""");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,7 +52,7 @@ public partial class Utility
|
||||
var expiryString = inv.MaxAge is null or 0 || inv.CreatedAt is null
|
||||
? "∞"
|
||||
: (inv.CreatedAt.Value.AddSeconds(inv.MaxAge.Value).UtcDateTime - DateTime.UtcNow).ToString(
|
||||
@"d\.hh\:mm\:ss");
|
||||
"""d\.hh\:mm\:ss""");
|
||||
var creator = inv.Inviter.ToString().TrimTo(25);
|
||||
var usesString = $"{inv.Uses} / {(inv.MaxUses == 0 ? "∞" : inv.MaxUses?.ToString())}";
|
||||
|
||||
|
@@ -782,13 +782,15 @@ public sealed class PatronageService
|
||||
patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(),
|
||||
true)
|
||||
.AddField("Instructions",
|
||||
@"*- Within the next **1-2 minutes** you will have all of the benefits of the Tier you've subscribed to.*
|
||||
*- You can check your benefits on <https://www.patreon.com/join/nadekobot>*
|
||||
*- You can use the `.patron` command in this chat to check your current quota usage for the Patron-only commands*
|
||||
*- **ALL** of the servers that you **own** will enjoy your Patron benefits.*
|
||||
*- You can use any of the commands available in your tier on any server (assuming you have sufficient permissions to run those commands)*
|
||||
*- Any user in any of your servers can use Patron-only commands, but they will spend **your quota**, which is why it's recommended to use Nadeko's command cooldown system (.h .cmdcd) or permission system to limit the command usage for your server members.*
|
||||
*- Permission guide can be found here if you're not familiar with it: <https://nadekobot.readthedocs.io/en/latest/permissions-system/>*",
|
||||
"""
|
||||
*- Within the next **1-2 minutes** you will have all of the benefits of the Tier you've subscribed to.*
|
||||
*- You can check your benefits on <https://www.patreon.com/join/nadekobot>*
|
||||
*- You can use the `.patron` command in this chat to check your current quota usage for the Patron-only commands*
|
||||
*- **ALL** of the servers that you **own** will enjoy your Patron benefits.*
|
||||
*- You can use any of the commands available in your tier on any server (assuming you have sufficient permissions to run those commands)*
|
||||
*- Any user in any of your servers can use Patron-only commands, but they will spend **your quota**, which is why it's recommended to use Nadeko's command cooldown system (.h .cmdcd) or permission system to limit the command usage for your server members.*
|
||||
*- Permission guide can be found here if you're not familiar with it: <https://nadekobot.readthedocs.io/en/latest/permissions-system/>*
|
||||
""",
|
||||
isInline: false)
|
||||
.WithFooter($"platform id: {patron.UniquePlatformUserId}");
|
||||
|
||||
|
@@ -13,12 +13,14 @@ public partial class Utility
|
||||
public partial class QuoteCommands : NadekoModule
|
||||
{
|
||||
private const string PREPEND_EXPORT =
|
||||
@"# Keys are keywords, Each key has a LIST of quotes in the following format:
|
||||
# - id: Alphanumeric id used for commands related to the quote. (Note, when using .quotesimport, a new id will be generated.)
|
||||
# an: Author name
|
||||
# aid: Author id
|
||||
# txt: Quote text
|
||||
";
|
||||
"""
|
||||
# Keys are keywords, Each key has a LIST of quotes in the following format:
|
||||
# - id: Alphanumeric id used for commands related to the quote. (Note, when using .quotesimport, a new id will be generated.)
|
||||
# an: Author name
|
||||
# aid: Author id
|
||||
# txt: Quote text
|
||||
|
||||
""";
|
||||
|
||||
private static readonly ISerializer _exportSerializer = new SerializerBuilder()
|
||||
.WithEventEmitter(args
|
||||
|
@@ -9,58 +9,68 @@ namespace NadekoBot.Modules.Xp;
|
||||
[Cloneable]
|
||||
public sealed partial class XpConfig : ICloneable<XpConfig>
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
[Comment("""DO NOT CHANGE""")]
|
||||
public int Version { get; set; } = 5;
|
||||
|
||||
[Comment(@"How much XP will the users receive per message")]
|
||||
[Comment("""How much XP will the users receive per message""")]
|
||||
public int XpPerMessage { get; set; } = 3;
|
||||
|
||||
[Comment(@"How often can the users receive XP in minutes")]
|
||||
[Comment("""How often can the users receive XP in minutes""")]
|
||||
public int MessageXpCooldown { get; set; } = 5;
|
||||
|
||||
[Comment(@"Amount of xp users gain from posting an image")]
|
||||
[Comment("""Amount of xp users gain from posting an image""")]
|
||||
public int XpFromImage { get; set; } = 0;
|
||||
|
||||
[Comment(@"Average amount of xp earned per minute in VC")]
|
||||
[Comment("""Average amount of xp earned per minute in VC""")]
|
||||
public double VoiceXpPerMinute { get; set; } = 0;
|
||||
|
||||
[Comment(@"The maximum amount of minutes the bot will keep track of a user in a voice channel")]
|
||||
[Comment("""The maximum amount of minutes the bot will keep track of a user in a voice channel""")]
|
||||
public int VoiceMaxMinutes { get; set; } = 720;
|
||||
|
||||
[Comment(@"The amount of currency users will receive for each point of global xp that they earn")]
|
||||
[Comment("""The amount of currency users will receive for each point of global xp that they earn""")]
|
||||
public float CurrencyPerXp { get; set; } = 0;
|
||||
|
||||
[Comment(@"Xp Shop config")]
|
||||
[Comment("""Xp Shop config""")]
|
||||
public ShopConfig Shop { get; set; } = new();
|
||||
|
||||
public sealed class ShopConfig
|
||||
{
|
||||
[Comment(@"Whether the xp shop is enabled
|
||||
True -> Users can access the xp shop using .xpshop command
|
||||
False -> Users can't access the xp shop")]
|
||||
[Comment("""
|
||||
Whether the xp shop is enabled
|
||||
True -> Users can access the xp shop using .xpshop command
|
||||
False -> Users can't access the xp shop
|
||||
""")]
|
||||
public bool IsEnabled { get; set; } = false;
|
||||
|
||||
[Comment(@"Which patron tier do users need in order to use the .xpshop bgs command
|
||||
Leave at 'None' if patron system is disabled or you don't want any restrictions")]
|
||||
[Comment("""
|
||||
Which patron tier do users need in order to use the .xpshop bgs command
|
||||
Leave at 'None' if patron system is disabled or you don't want any restrictions
|
||||
""")]
|
||||
public PatronTier BgsTierRequirement { get; set; } = PatronTier.None;
|
||||
|
||||
[Comment(@"Which patron tier do users need in order to use the .xpshop frames command
|
||||
Leave at 'None' if patron system is disabled or you don't want any restrictions")]
|
||||
[Comment("""
|
||||
Which patron tier do users need in order to use the .xpshop frames command
|
||||
Leave at 'None' if patron system is disabled or you don't want any restrictions
|
||||
""")]
|
||||
public PatronTier FramesTierRequirement { get; set; } = PatronTier.None;
|
||||
|
||||
[Comment(@"Frames available for sale. Keys are unique IDs.
|
||||
Do not change keys as they are not publicly visible. Only change properties (name, price, id)
|
||||
Removing a key which previously existed means that all previous purchases will also be unusable.
|
||||
To remove an item from the shop, but keep previous purchases, set the price to -1")]
|
||||
[Comment("""
|
||||
Frames available for sale. Keys are unique IDs.
|
||||
Do not change keys as they are not publicly visible. Only change properties (name, price, id)
|
||||
Removing a key which previously existed means that all previous purchases will also be unusable.
|
||||
To remove an item from the shop, but keep previous purchases, set the price to -1
|
||||
""")]
|
||||
public Dictionary<string, ShopItemInfo>? Frames { get; set; } = new()
|
||||
{
|
||||
{"default", new() {Name = "No frame", Price = 0, Url = string.Empty}}
|
||||
};
|
||||
|
||||
[Comment(@"Backgrounds available for sale. Keys are unique IDs.
|
||||
Do not change keys as they are not publicly visible. Only change properties (name, price, id)
|
||||
Removing a key which previously existed means that all previous purchases will also be unusable.
|
||||
To remove an item from the shop, but keep previous purchases, set the price to -1")]
|
||||
[Comment("""
|
||||
Backgrounds available for sale. Keys are unique IDs.
|
||||
Do not change keys as they are not publicly visible. Only change properties (name, price, id)
|
||||
Removing a key which previously existed means that all previous purchases will also be unusable.
|
||||
To remove an item from the shop, but keep previous purchases, set the price to -1
|
||||
""")]
|
||||
public Dictionary<string, ShopItemInfo>? Bgs { get; set; } = new()
|
||||
{
|
||||
{"default", new() {Name = "Default Background", Price = 0, Url = string.Empty}}
|
||||
@@ -69,19 +79,19 @@ To remove an item from the shop, but keep previous purchases, set the price to -
|
||||
|
||||
public sealed class ShopItemInfo
|
||||
{
|
||||
[Comment(@"Visible name of the item")]
|
||||
[Comment("""Visible name of the item""")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Comment(@"Price of the item. Set to -1 if you no longer want to sell the item but want the users to be able to keep their old purchase")]
|
||||
[Comment("""Price of the item. Set to -1 if you no longer want to sell the item but want the users to be able to keep their old purchase""")]
|
||||
public int Price { get; set; }
|
||||
|
||||
[Comment(@"Direct url to the .png image which will be applied to the user's XP card")]
|
||||
[Comment("""Direct url to the .png image which will be applied to the user's XP card""")]
|
||||
public string Url { get; set; }
|
||||
|
||||
[Comment(@"Optional preview url which will show instead of the real URL in the shop ")]
|
||||
[Comment("""Optional preview url which will show instead of the real URL in the shop """)]
|
||||
public string Preview { get; set; }
|
||||
|
||||
[Comment(@"Optional description of the item")]
|
||||
[Comment("""Optional description of the item""")]
|
||||
public string Desc { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ public partial class Xp
|
||||
.OrderBy(x => x.Level)
|
||||
.Select(x =>
|
||||
{
|
||||
var sign = !x.Remove ? @"✅ " : @"❌ ";
|
||||
var sign = !x.Remove ? "✅ " : "❌ ";
|
||||
|
||||
var str = ctx.Guild.GetRole(x.RoleId)?.ToString();
|
||||
|
||||
|
Reference in New Issue
Block a user