mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 09:18:27 -04:00
- Added Cloneable deep clone source generator nuget package
- Configs are no cloned using generated clone, not by serializing/deserializing - Arrays/Lists (collections in geneeral) are still not cloned properly - Removed GetRawData from config as it is no longer needed, new clone is very fast - Added ICloneable<T> which all configs implement - Cleaned up config classes/code
This commit is contained in:
@@ -141,7 +141,6 @@ namespace NadekoBot
|
||||
.AddSingleton<IReadyExecutor>(x => (IReadyExecutor)x.GetRequiredService<ICoordinator>());
|
||||
}
|
||||
|
||||
// todo no public bot attribute
|
||||
svcs.Scan(scan => scan
|
||||
.FromAssemblyOf<IReadyExecutor>()
|
||||
.AddClasses(classes => classes.AssignableToAny(
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Cloneable;
|
||||
using NadekoBot.Common.Yml;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using YamlDotNet.Core;
|
||||
@@ -7,7 +8,8 @@ using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Common.Configs
|
||||
{
|
||||
public sealed class BotConfig
|
||||
[Cloneable]
|
||||
public sealed partial class BotConfig : ICloneable<BotConfig>
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
public int Version { get; set; }
|
||||
@@ -66,6 +68,7 @@ note: This setting is primarily used if you're afraid of raids, or you're runnin
|
||||
servers might get hundreds of people join at once. This is used to prevent the bot from getting ratelimited,
|
||||
and (slightly) reduce the greet spam in those servers.")]
|
||||
public bool GroupGreets { get; set; }
|
||||
|
||||
[Comment(@"Whether the bot will rotate through all specified statuses.
|
||||
This setting can be changed via .rots command.
|
||||
See RotatingStatuses submodule in Administration.")]
|
||||
@@ -127,7 +130,8 @@ See RotatingStatuses submodule in Administration.")]
|
||||
}
|
||||
}
|
||||
|
||||
public class BlockedConfig
|
||||
[Cloneable]
|
||||
public sealed partial class BlockedConfig
|
||||
{
|
||||
public HashSet<string> Commands { get; set; }
|
||||
public HashSet<string> Modules { get; set; }
|
||||
@@ -139,7 +143,8 @@ See RotatingStatuses submodule in Administration.")]
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorConfig
|
||||
[Cloneable]
|
||||
public partial class ColorConfig
|
||||
{
|
||||
[Comment(@"Color used for embed responses when command successfully executes")]
|
||||
public Rgba32 Ok { get; set; }
|
||||
@@ -157,6 +162,7 @@ See RotatingStatuses submodule in Administration.")]
|
||||
Pending = Rgba32.ParseHex("faa61a");
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConsoleOutputType
|
||||
{
|
||||
Normal = 0,
|
||||
|
7
src/NadekoBot/Common/ICloneable.cs
Normal file
7
src/NadekoBot/Common/ICloneable.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace NadekoBot.Common
|
||||
{
|
||||
public interface ICloneable<T> where T : new()
|
||||
{
|
||||
public T Clone();
|
||||
}
|
||||
}
|
@@ -233,7 +233,7 @@ namespace NadekoBot.Modules.Administration.Services
|
||||
public async Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
var bs = _bss.Data;
|
||||
if (msg.Channel is IDMChannel && _bss.Data.ForwardMessages && ownerChannels.Any())
|
||||
if (msg.Channel is IDMChannel && bs.ForwardMessages && ownerChannels.Any())
|
||||
{
|
||||
var title = _strings.GetText("dm_from") +
|
||||
$" [{msg.Author}]({msg.Author.Id})";
|
||||
|
@@ -13,10 +13,10 @@ namespace NadekoBot.Modules.Gambling.Common
|
||||
}
|
||||
|
||||
|
||||
private readonly IOrderedEnumerable<GamblingConfig.BetRollConfig.Pair> _thresholdPairs;
|
||||
private readonly IOrderedEnumerable<BetRollPair> _thresholdPairs;
|
||||
private readonly Random _rng;
|
||||
|
||||
public Betroll(GamblingConfig.BetRollConfig settings)
|
||||
public Betroll(BetRollConfig settings)
|
||||
{
|
||||
_thresholdPairs = settings.Pairs.OrderByDescending(x => x.WhenAbove);
|
||||
_rng = new Random();
|
||||
|
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cloneable;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Common.Yml;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Common
|
||||
{
|
||||
public sealed class GamblingConfig
|
||||
[Cloneable]
|
||||
public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
|
||||
{
|
||||
public GamblingConfig()
|
||||
{
|
||||
@@ -17,10 +20,10 @@ namespace NadekoBot.Modules.Gambling.Common
|
||||
Timely = new TimelyConfig();
|
||||
Decay = new DecayConfig();
|
||||
}
|
||||
|
||||
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
public int Version { get; set; } = 1;
|
||||
|
||||
|
||||
[Comment(@"Currency settings")]
|
||||
public CurrencyConfig Currency { get; set; }
|
||||
|
||||
@@ -30,257 +33,247 @@ namespace NadekoBot.Modules.Gambling.Common
|
||||
[Comment(@"Maximum amount users can bet
|
||||
Set 0 for unlimited")]
|
||||
public int MaxBet { get; set; } = 0;
|
||||
|
||||
|
||||
[Comment(@"Settings for betflip command")]
|
||||
public BetFlipConfig BetFlip { get; set; }
|
||||
|
||||
[Comment(@"Settings for betroll command")]
|
||||
public BetRollConfig BetRoll { get; set; }
|
||||
|
||||
|
||||
[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)")]
|
||||
public TimelyConfig Timely { get; set; }
|
||||
|
||||
[Comment(@"How much will each user's owned currency decay over time.")]
|
||||
public DecayConfig Decay { get; set; }
|
||||
|
||||
[Comment(@"Settings for Wheel Of Fortune command.")]
|
||||
public WheelOfFortuneSettings WheelOfFortune { get; set; }
|
||||
|
||||
[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.")]
|
||||
public decimal PatreonCurrencyPerCent { get; set; } = 1;
|
||||
}
|
||||
|
||||
public class CurrencyConfig
|
||||
{
|
||||
[Comment(@"What is the emoji/character which represents the currency")]
|
||||
public string Sign { get; set; } = "🌸";
|
||||
|
||||
[Comment(@"What is the name of the currency")]
|
||||
public string Name { get; set; } = "Nadeko Flower";
|
||||
}
|
||||
public class CurrencyConfig
|
||||
{
|
||||
[Comment(@"What is the emoji/character which represents the currency")]
|
||||
public string Sign { get; set; } = "🌸";
|
||||
|
||||
public class TimelyConfig
|
||||
{
|
||||
[Comment(@"How much currency will the users get every time they run .timely command
|
||||
[Comment(@"What is the name of the currency")]
|
||||
public string Name { get; set; } = "Nadeko Flower";
|
||||
}
|
||||
|
||||
[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")]
|
||||
public int Amount { get; set; } = 0;
|
||||
public int Amount { get; set; } = 0;
|
||||
|
||||
[Comment(@"How often (in hours) can users claim currency with .timely command
|
||||
[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;
|
||||
}
|
||||
public int Cooldown { get; set; } = 24;
|
||||
}
|
||||
|
||||
public class BetFlipConfig
|
||||
{
|
||||
[Comment(@"Bet multiplier if user guesses correctly")]
|
||||
public decimal Multiplier { get; set; } = 1.95M;
|
||||
}
|
||||
[Cloneable]
|
||||
public partial class BetFlipConfig
|
||||
{
|
||||
[Comment(@"Bet multiplier if user guesses correctly")]
|
||||
public decimal Multiplier { get; set; } = 1.95M;
|
||||
}
|
||||
|
||||
public class BetRollConfig
|
||||
{
|
||||
[Comment(@"When betroll is played, user will roll a number 0-100.
|
||||
[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.")]
|
||||
public Pair[] Pairs { get; set; } = Array.Empty<Pair>();
|
||||
public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>();
|
||||
|
||||
public BetRollConfig()
|
||||
{
|
||||
Pairs = new BetRollConfig.Pair[]
|
||||
{
|
||||
new BetRollConfig.Pair(99, 10),
|
||||
new BetRollConfig.Pair(90, 4),
|
||||
new BetRollConfig.Pair(66, 2)
|
||||
};
|
||||
}
|
||||
|
||||
public class Pair
|
||||
{
|
||||
|
||||
public int WhenAbove { get; set; }
|
||||
|
||||
public float MultiplyBy { get; set; }
|
||||
|
||||
public Pair()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Pair(int threshold, int multiplier)
|
||||
{
|
||||
WhenAbove = threshold;
|
||||
MultiplyBy = multiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GenerationConfig
|
||||
public BetRollConfig()
|
||||
{
|
||||
[Comment(@"when currency is generated, should it also have a random password
|
||||
Pairs = new BetRollPair[]
|
||||
{
|
||||
new BetRollPair { WhenAbove = 99, MultiplyBy = 10 },
|
||||
new BetRollPair { WhenAbove = 90, MultiplyBy = 4 },
|
||||
new BetRollPair { WhenAbove = 66, MultiplyBy = 2 }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[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")]
|
||||
public bool HasPassword { get; set; } = true;
|
||||
public bool HasPassword { get; set; } = true;
|
||||
|
||||
[Comment(@"Every message sent has a certain % chance to generate the currency
|
||||
[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;
|
||||
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")]
|
||||
public int GenCooldown { get; set; } = 10;
|
||||
[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")]
|
||||
public int MinAmount { get; set; } = 1;
|
||||
[Comment(@"Minimum amount of currency that can spawn")]
|
||||
public int MinAmount { get; set; } = 1;
|
||||
|
||||
[Comment(@"Maximum amount of currency that can spawn.
|
||||
[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;
|
||||
}
|
||||
public int MaxAmount { get; set; } = 1;
|
||||
}
|
||||
|
||||
public class DecayConfig
|
||||
{
|
||||
[Comment(@"Percentage of user's current currency which will be deducted every 24h.
|
||||
[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)")]
|
||||
public decimal Percent { get; set; } = 0;
|
||||
public decimal Percent { get; set; } = 0;
|
||||
|
||||
[Comment(@"Maximum amount of user's currency that can decay at each interval. 0 for unlimited.")]
|
||||
public int MaxDecay { get; set; } = 0;
|
||||
[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.")]
|
||||
public int MinThreshold { get; set; } = 99;
|
||||
[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")]
|
||||
public int HourInterval { get; set; } = 24;
|
||||
}
|
||||
[Comment(@"How often, in hours, does the decay run. Default is 24 hours")]
|
||||
public int HourInterval { get; set; } = 24;
|
||||
}
|
||||
|
||||
public class WheelOfFortuneSettings
|
||||
[Cloneable]
|
||||
public partial class WheelOfFortuneSettings
|
||||
{
|
||||
[Comment(@"Self-Explanatory. Has to have 8 values, otherwise the command won't work.")]
|
||||
public decimal[] Multipliers { get; set; }
|
||||
|
||||
public WheelOfFortuneSettings()
|
||||
{
|
||||
[Comment(@"Self-Explanatory. Has to have 8 values, otherwise the command won't work.")]
|
||||
public decimal[] Multipliers { get; set; }
|
||||
|
||||
public WheelOfFortuneSettings()
|
||||
Multipliers = new decimal[]
|
||||
{
|
||||
Multipliers = new decimal[]
|
||||
{
|
||||
1.7M,
|
||||
1.5M,
|
||||
0.2M,
|
||||
0.1M,
|
||||
0.3M,
|
||||
0.5M,
|
||||
1.2M,
|
||||
2.4M,
|
||||
};
|
||||
}
|
||||
1.7M,
|
||||
1.5M,
|
||||
0.2M,
|
||||
0.1M,
|
||||
0.3M,
|
||||
0.5M,
|
||||
1.2M,
|
||||
2.4M,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class WaifuConfig
|
||||
[Cloneable]
|
||||
public sealed partial class WaifuConfig
|
||||
{
|
||||
[Comment(@"Minimum price a waifu can have")]
|
||||
public int MinPrice { get; set; } = 50;
|
||||
|
||||
public MultipliersData Multipliers { get; set; } = new MultipliersData();
|
||||
|
||||
[Comment(@"List of items available for gifting.")]
|
||||
public List<WaifuItemModel> Items { get; set; } = new List<WaifuItemModel>();
|
||||
|
||||
public WaifuConfig()
|
||||
{
|
||||
[Comment(@"Minimum price a waifu can have")]
|
||||
public int MinPrice { get; set; } = 50;
|
||||
public MultipliersData Multipliers { get; set; } = new MultipliersData();
|
||||
|
||||
[Comment(@"List of items available for gifting.")]
|
||||
public List<WaifuItemModel> Items { get; set; } = new List<WaifuItemModel>();
|
||||
|
||||
public WaifuConfig()
|
||||
Items = new()
|
||||
{
|
||||
Items = new List<WaifuItemModel>()
|
||||
{
|
||||
new WaifuItemModel("🥔", 5, "Potato"),
|
||||
new WaifuItemModel("🍪", 10, "Cookie"),
|
||||
new WaifuItemModel("🥖", 20, "Bread"),
|
||||
new WaifuItemModel("🍭", 30, "Lollipop"),
|
||||
new WaifuItemModel("🌹", 50, "Rose"),
|
||||
new WaifuItemModel("🍺", 70, "Beer"),
|
||||
new WaifuItemModel("🌮", 85, "Taco"),
|
||||
new WaifuItemModel("💌", 100, "LoveLetter"),
|
||||
new WaifuItemModel("🥛", 125, "Milk"),
|
||||
new WaifuItemModel("🍕", 150, "Pizza"),
|
||||
new WaifuItemModel("🍫", 200, "Chocolate"),
|
||||
new WaifuItemModel("🍦", 250, "Icecream"),
|
||||
new WaifuItemModel("🍣", 300, "Sushi"),
|
||||
new WaifuItemModel("🍚", 400, "Rice"),
|
||||
new WaifuItemModel("🍉", 500, "Watermelon"),
|
||||
new WaifuItemModel("🍱", 600, "Bento"),
|
||||
new WaifuItemModel("🎟", 800, "MovieTicket"),
|
||||
new WaifuItemModel("🍰", 1000, "Cake"),
|
||||
new WaifuItemModel("📔", 1500, "Book"),
|
||||
new WaifuItemModel("🐱", 2000, "Cat"),
|
||||
new WaifuItemModel("🐶", 2001, "Dog"),
|
||||
new WaifuItemModel("🐼", 2500, "Panda"),
|
||||
new WaifuItemModel("💄", 3000, "Lipstick"),
|
||||
new WaifuItemModel("👛", 3500, "Purse"),
|
||||
new WaifuItemModel("📱", 4000, "iPhone"),
|
||||
new WaifuItemModel("👗", 4500, "Dress"),
|
||||
new WaifuItemModel("💻", 5000, "Laptop"),
|
||||
new WaifuItemModel("🎻", 7500, "Violin"),
|
||||
new WaifuItemModel("🎹", 8000, "Piano"),
|
||||
new WaifuItemModel("🚗", 9000, "Car"),
|
||||
new WaifuItemModel("💍", 10000, "Ring"),
|
||||
new WaifuItemModel("🛳", 12000, "Ship"),
|
||||
new WaifuItemModel("🏠", 15000, "House"),
|
||||
new WaifuItemModel("🚁", 20000, "Helicopter"),
|
||||
new WaifuItemModel("🚀", 30000, "Spaceship"),
|
||||
new WaifuItemModel("🌕", 50000, "Moon")
|
||||
};
|
||||
}
|
||||
new("🥔", 5, "Potato"),
|
||||
new("🍪", 10, "Cookie"),
|
||||
new("🥖", 20, "Bread"),
|
||||
new("🍭", 30, "Lollipop"),
|
||||
new("🌹", 50, "Rose"),
|
||||
new("🍺", 70, "Beer"),
|
||||
new("🌮", 85, "Taco"),
|
||||
new("💌", 100, "LoveLetter"),
|
||||
new("🥛", 125, "Milk"),
|
||||
new("🍕", 150, "Pizza"),
|
||||
new("🍫", 200, "Chocolate"),
|
||||
new("🍦", 250, "Icecream"),
|
||||
new("🍣", 300, "Sushi"),
|
||||
new("🍚", 400, "Rice"),
|
||||
new("🍉", 500, "Watermelon"),
|
||||
new("🍱", 600, "Bento"),
|
||||
new("🎟", 800, "MovieTicket"),
|
||||
new("🍰", 1000, "Cake"),
|
||||
new("📔", 1500, "Book"),
|
||||
new("🐱", 2000, "Cat"),
|
||||
new("🐶", 2001, "Dog"),
|
||||
new("🐼", 2500, "Panda"),
|
||||
new("💄", 3000, "Lipstick"),
|
||||
new("👛", 3500, "Purse"),
|
||||
new("📱", 4000, "iPhone"),
|
||||
new("👗", 4500, "Dress"),
|
||||
new("💻", 5000, "Laptop"),
|
||||
new("🎻", 7500, "Violin"),
|
||||
new("🎹", 8000, "Piano"),
|
||||
new("🚗", 9000, "Car"),
|
||||
new("💍", 10000, "Ring"),
|
||||
new("🛳", 12000, "Ship"),
|
||||
new("🏠", 15000, "House"),
|
||||
new("🚁", 20000, "Helicopter"),
|
||||
new("🚀", 30000, "Spaceship"),
|
||||
new("🌕", 50000, "Moon")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class MultipliersData
|
||||
{
|
||||
[Comment(@"Multiplier for waifureset. Default 150.
|
||||
[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")]
|
||||
public int WaifuReset { get; set; } = 150;
|
||||
public int WaifuReset { get; set; } = 150;
|
||||
|
||||
[Comment(@"The minimum amount of currency that you have to pay
|
||||
[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;
|
||||
public decimal NormalClaim { get; set; } = 1.1m;
|
||||
|
||||
[Comment(@"The minimum amount of currency that you have to pay
|
||||
[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;
|
||||
public decimal CrushClaim { get; set; } = 0.88M;
|
||||
|
||||
[Comment(@"When divorcing a waifu, her new value will be her current value multiplied by this number.
|
||||
[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;
|
||||
public decimal DivorceNewValue { get; set; } = 0.75M;
|
||||
|
||||
[Comment(@"All gift prices will be multiplied by this number.
|
||||
[Comment(@"All gift prices will be multiplied by this number.
|
||||
Default 1 (meaning no effect)")]
|
||||
public decimal AllGiftPrices { get; set; } = 1.0M;
|
||||
public decimal AllGiftPrices { get; set; } = 1.0M;
|
||||
|
||||
[Comment(@"What percentage of the value of the gift will a waifu gain when she's gifted.
|
||||
[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;
|
||||
}
|
||||
}
|
||||
public decimal GiftEffect { get; set; } = 0.95M;
|
||||
}
|
||||
|
||||
public class WaifuItemModel
|
||||
|
||||
[Cloneable]
|
||||
public sealed partial class WaifuItemModel
|
||||
{
|
||||
public string ItemEmoji { get; set; }
|
||||
|
||||
public int Price { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public WaifuItemModel()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public WaifuItemModel(string itemEmoji, int price, string name)
|
||||
{
|
||||
ItemEmoji = itemEmoji;
|
||||
@@ -290,4 +283,12 @@ Example: If a waifu is worth 1000, and she receives a gift worth 100, her new va
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
|
||||
|
||||
[Cloneable]
|
||||
public sealed partial class BetRollPair
|
||||
{
|
||||
public int WhenAbove { get; set; }
|
||||
public float MultiplyBy { get; set; }
|
||||
}
|
||||
}
|
@@ -511,7 +511,7 @@ namespace NadekoBot.Modules.Gambling.Services
|
||||
public IReadOnlyList<WaifuItemModel> GetWaifuItems()
|
||||
{
|
||||
var conf = _gss.Data;
|
||||
return _gss.Data.Waifu.Items
|
||||
return conf.Waifu.Items
|
||||
.Select(x => new WaifuItemModel(x.ItemEmoji, (int)(x.Price * conf.Waifu.Multipliers.AllGiftPrices), x.Name))
|
||||
.ToList();
|
||||
}
|
||||
|
@@ -1,9 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Cloneable;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Common.Yml;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Common
|
||||
{
|
||||
public sealed class GamesConfig
|
||||
[Cloneable]
|
||||
public sealed partial class GamesConfig : ICloneable<GamesConfig>
|
||||
{
|
||||
[Comment("Trivia related settings (.t command)")]
|
||||
public TriviaConfig Trivia { get; set; } = new TriviaConfig()
|
||||
@@ -11,7 +14,7 @@ namespace NadekoBot.Modules.Games.Common
|
||||
CurrencyReward = 0,
|
||||
MinimumWinReq = 1,
|
||||
};
|
||||
|
||||
|
||||
[Comment("List of responses for the .8ball command. A random one will be selected every time")]
|
||||
public List<string> EightBallResponses { get; set; } = new List<string>()
|
||||
{
|
||||
@@ -43,18 +46,19 @@ namespace NadekoBot.Modules.Games.Common
|
||||
[Comment("List of animals which will be used for the animal race game (.race)")]
|
||||
public List<RaceAnimal> RaceAnimals { get; set; } = new List<RaceAnimal>()
|
||||
{
|
||||
new RaceAnimal {Icon = "🐼", Name = "Panda"},
|
||||
new RaceAnimal {Icon = "🐻", Name = "Bear"},
|
||||
new RaceAnimal {Icon = "🐧", Name = "Pengu"},
|
||||
new RaceAnimal {Icon = "🐨", Name = "Koala"},
|
||||
new RaceAnimal {Icon = "🐬", Name = "Dolphin"},
|
||||
new RaceAnimal {Icon = "🐞", Name = "Ladybird"},
|
||||
new RaceAnimal {Icon = "🦀", Name = "Crab"},
|
||||
new RaceAnimal {Icon = "🦄", Name = "Unicorn"}
|
||||
new RaceAnimal { Icon = "🐼", Name = "Panda" },
|
||||
new RaceAnimal { Icon = "🐻", Name = "Bear" },
|
||||
new RaceAnimal { Icon = "🐧", Name = "Pengu" },
|
||||
new RaceAnimal { Icon = "🐨", Name = "Koala" },
|
||||
new RaceAnimal { Icon = "🐬", Name = "Dolphin" },
|
||||
new RaceAnimal { Icon = "🐞", Name = "Ladybird" },
|
||||
new RaceAnimal { Icon = "🦀", Name = "Crab" },
|
||||
new RaceAnimal { Icon = "🦄", Name = "Unicorn" }
|
||||
};
|
||||
}
|
||||
|
||||
public sealed class TriviaConfig
|
||||
[Cloneable]
|
||||
public sealed partial class TriviaConfig
|
||||
{
|
||||
[Comment("The amount of currency awarded to the winner of the trivia game.")]
|
||||
public long CurrencyReward { get; set; } = 0;
|
||||
@@ -64,7 +68,8 @@ a smaller win requirement than the one specified by this setting.")]
|
||||
public int MinimumWinReq { get; set; } = 1;
|
||||
}
|
||||
|
||||
public sealed class RaceAnimal
|
||||
[Cloneable]
|
||||
public sealed partial class RaceAnimal
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
@@ -34,8 +34,8 @@ namespace NadekoBot.Modules.Help.Services
|
||||
|
||||
|
||||
_rep = new ReplacementBuilder()
|
||||
.WithOverride("%prefix%", () => _bss.GetRawData().Prefix)
|
||||
.WithOverride("%bot.prefix%", () => _bss.GetRawData().Prefix)
|
||||
.WithOverride("%prefix%", () => _bss.Data.Prefix)
|
||||
.WithOverride("%bot.prefix%", () => _bss.Data.Prefix)
|
||||
.Build();
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,11 @@
|
||||
using NadekoBot.Common.Yml;
|
||||
using Cloneable;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Common.Yml;
|
||||
|
||||
namespace NadekoBot.Modules.Xp
|
||||
{
|
||||
public sealed class XpConfig
|
||||
[Cloneable]
|
||||
public sealed partial class XpConfig : ICloneable<XpConfig>
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
public int Version { get; set; } = 2;
|
||||
|
@@ -623,15 +623,16 @@ namespace NadekoBot.Modules.Xp.Services
|
||||
if (!ShouldTrackXp(user, arg.Channel.Id))
|
||||
return;
|
||||
|
||||
var xpConf = _xpConfig.Data;
|
||||
var xp = 0;
|
||||
if (arg.Attachments.Any(a => a.Height >= 128 && a.Width >= 128))
|
||||
{
|
||||
xp = _xpConfig.GetRawData().XpFromImage;
|
||||
xp = xpConf.XpFromImage;
|
||||
}
|
||||
|
||||
if (arg.Content.Contains(' ') || arg.Content.Length >= 5)
|
||||
{
|
||||
xp = Math.Max(xp, _xpConfig.GetRawData().XpPerMessage);
|
||||
xp = Math.Max(xp, xpConf.XpPerMessage);
|
||||
}
|
||||
|
||||
if (xp <= 0)
|
||||
|
@@ -11,6 +11,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp" Version="0.16.0" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.1.4" />
|
||||
<PackageReference Include="Cloneable" Version="1.3.0" />
|
||||
<PackageReference Include="CodeHollow.FeedReader" Version="1.2.1" />
|
||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||
<PackageReference Include="Discord.Net" Version="2.4.0" />
|
||||
|
@@ -142,7 +142,7 @@ namespace NadekoBot.Services
|
||||
|
||||
private Task LogSuccessfulExecution(IUserMessage usrMsg, ITextChannel channel, params int[] execPoints)
|
||||
{
|
||||
if (_bss.GetRawData().ConsoleOutputType == ConsoleOutputType.Normal)
|
||||
if (_bss.Data.ConsoleOutputType == ConsoleOutputType.Normal)
|
||||
{
|
||||
Log.Information($"Command Executed after " + string.Join("/", execPoints.Select(x => (x * _oneThousandth).ToString("F3"))) + "s\n\t" +
|
||||
"User: {0}\n\t" +
|
||||
@@ -168,7 +168,7 @@ namespace NadekoBot.Services
|
||||
|
||||
private void LogErroredExecution(string errorMessage, IUserMessage usrMsg, ITextChannel channel, params int[] execPoints)
|
||||
{
|
||||
if (_bss.GetRawData().ConsoleOutputType == ConsoleOutputType.Normal)
|
||||
if (_bss.Data.ConsoleOutputType == ConsoleOutputType.Normal)
|
||||
{
|
||||
Log.Warning($"Command Errored after " + string.Join("/", execPoints.Select(x => (x * _oneThousandth).ToString("F3"))) + "s\n\t" +
|
||||
"User: {0}\n\t" +
|
||||
|
@@ -83,7 +83,7 @@ namespace NadekoBot.Services
|
||||
.EmbedAsync(new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle($"Received Currency")
|
||||
.AddField("Amount", amount + _gss.Data.Currency.Sign)
|
||||
.AddField("Amount", amount + sign)
|
||||
.AddField("Reason", reason));
|
||||
}
|
||||
catch
|
||||
|
@@ -4,14 +4,10 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Common.Yml;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Common.Configs;
|
||||
using NadekoBot.Common.JsonConverters;
|
||||
using Rgba32Converter = NadekoBot.Common.JsonConverters.Rgba32Converter;
|
||||
using CultureInfoConverter = NadekoBot.Common.JsonConverters.CultureInfoConverter;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
@@ -20,7 +16,7 @@ namespace NadekoBot.Services
|
||||
/// </summary>
|
||||
/// <typeparam name="TSettings">Type of the settings</typeparam>
|
||||
public abstract class ConfigServiceBase<TSettings> : IConfigService
|
||||
where TSettings : new()
|
||||
where TSettings : ICloneable<TSettings>, new()
|
||||
{
|
||||
protected readonly string _filePath;
|
||||
protected readonly IConfigSeria _serializer;
|
||||
@@ -29,8 +25,8 @@ namespace NadekoBot.Services
|
||||
|
||||
protected TSettings _data;
|
||||
|
||||
// todo this has to be protected from mutation
|
||||
public TSettings Data => _data;
|
||||
// todo future config arrays are not copied - they're not protected from mutations
|
||||
public TSettings Data => _data.Clone();
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
@@ -65,21 +61,6 @@ namespace NadekoBot.Services
|
||||
return default;
|
||||
}
|
||||
|
||||
private static readonly JsonSerializerOptions serializerOptions = new JsonSerializerOptions()
|
||||
{
|
||||
MaxDepth = 0,
|
||||
Converters = { new Rgba32Converter(), new CultureInfoConverter() }
|
||||
};
|
||||
private TSettings CreateCopy()
|
||||
{
|
||||
var serializedData = JsonSerializer.Serialize(_data, serializerOptions);
|
||||
return JsonSerializer.Deserialize<TSettings>(serializedData, serializerOptions);
|
||||
|
||||
// var serializedData = _serializer.Serialize(_data);
|
||||
//
|
||||
// return _serializer.Deserialize<TSettings>(serializedData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads data from disk. If file doesn't exist, it will be created with default values
|
||||
/// </summary>
|
||||
@@ -114,14 +95,6 @@ namespace NadekoBot.Services
|
||||
|
||||
}
|
||||
|
||||
public void ModifyConfig(Action<TSettings> action)
|
||||
{
|
||||
var copy = CreateCopy();
|
||||
action(copy);
|
||||
_data = copy;
|
||||
Save();
|
||||
PublishChange();
|
||||
}
|
||||
private void Save()
|
||||
{
|
||||
var strData = _serializer.Serialize(_data);
|
||||
@@ -162,9 +135,7 @@ namespace NadekoBot.Services
|
||||
var expr = (MemberExpression)selector.Body;
|
||||
var prop = (PropertyInfo)expr.Member;
|
||||
|
||||
var expressions = new List<MemberExpression>()
|
||||
{
|
||||
};
|
||||
var expressions = new List<MemberExpression>();
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -224,6 +195,13 @@ namespace NadekoBot.Services
|
||||
return success;
|
||||
}
|
||||
|
||||
public TSettings GetRawData() => _data;
|
||||
public void ModifyConfig(Action<TSettings> action)
|
||||
{
|
||||
var copy = Data;
|
||||
action(copy);
|
||||
_data = copy;
|
||||
Save();
|
||||
PublishChange();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user