- 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:
Kwoth
2021-07-06 17:08:16 +02:00
parent a8a4c9fb44
commit 0fc5f540d8
15 changed files with 237 additions and 236 deletions

View File

@@ -141,7 +141,6 @@ namespace NadekoBot
.AddSingleton<IReadyExecutor>(x => (IReadyExecutor)x.GetRequiredService<ICoordinator>()); .AddSingleton<IReadyExecutor>(x => (IReadyExecutor)x.GetRequiredService<ICoordinator>());
} }
// todo no public bot attribute
svcs.Scan(scan => scan svcs.Scan(scan => scan
.FromAssemblyOf<IReadyExecutor>() .FromAssemblyOf<IReadyExecutor>()
.AddClasses(classes => classes.AssignableToAny( .AddClasses(classes => classes.AssignableToAny(

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Cloneable;
using NadekoBot.Common.Yml; using NadekoBot.Common.Yml;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using YamlDotNet.Core; using YamlDotNet.Core;
@@ -7,7 +8,8 @@ using YamlDotNet.Serialization;
namespace NadekoBot.Common.Configs namespace NadekoBot.Common.Configs
{ {
public sealed class BotConfig [Cloneable]
public sealed partial class BotConfig : ICloneable<BotConfig>
{ {
[Comment(@"DO NOT CHANGE")] [Comment(@"DO NOT CHANGE")]
public int Version { get; set; } 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, 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.")] and (slightly) reduce the greet spam in those servers.")]
public bool GroupGreets { get; set; } public bool GroupGreets { get; set; }
[Comment(@"Whether the bot will rotate through all specified statuses. [Comment(@"Whether the bot will rotate through all specified statuses.
This setting can be changed via .rots command. This setting can be changed via .rots command.
See RotatingStatuses submodule in Administration.")] 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> Commands { get; set; }
public HashSet<string> Modules { 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")] [Comment(@"Color used for embed responses when command successfully executes")]
public Rgba32 Ok { get; set; } public Rgba32 Ok { get; set; }
@@ -157,6 +162,7 @@ See RotatingStatuses submodule in Administration.")]
Pending = Rgba32.ParseHex("faa61a"); Pending = Rgba32.ParseHex("faa61a");
} }
} }
public enum ConsoleOutputType public enum ConsoleOutputType
{ {
Normal = 0, Normal = 0,

View File

@@ -0,0 +1,7 @@
namespace NadekoBot.Common
{
public interface ICloneable<T> where T : new()
{
public T Clone();
}
}

View File

@@ -233,7 +233,7 @@ namespace NadekoBot.Modules.Administration.Services
public async Task LateExecute(IGuild guild, IUserMessage msg) public async Task LateExecute(IGuild guild, IUserMessage msg)
{ {
var bs = _bss.Data; 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") + var title = _strings.GetText("dm_from") +
$" [{msg.Author}]({msg.Author.Id})"; $" [{msg.Author}]({msg.Author.Id})";

View File

@@ -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; private readonly Random _rng;
public Betroll(GamblingConfig.BetRollConfig settings) public Betroll(BetRollConfig settings)
{ {
_thresholdPairs = settings.Pairs.OrderByDescending(x => x.WhenAbove); _thresholdPairs = settings.Pairs.OrderByDescending(x => x.WhenAbove);
_rng = new Random(); _rng = new Random();

View File

@@ -1,10 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Cloneable;
using NadekoBot.Common;
using NadekoBot.Common.Yml; using NadekoBot.Common.Yml;
namespace NadekoBot.Modules.Gambling.Common namespace NadekoBot.Modules.Gambling.Common
{ {
public sealed class GamblingConfig [Cloneable]
public sealed partial class GamblingConfig : ICloneable<GamblingConfig>
{ {
public GamblingConfig() public GamblingConfig()
{ {
@@ -46,14 +49,17 @@ Set 0 for unlimited")]
[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; } public DecayConfig Decay { get; set; }
[Comment(@"Settings for Wheel Of Fortune command.")] [Comment(@"Settings for Wheel Of Fortune command.")]
public WheelOfFortuneSettings WheelOfFortune { get; set; } public WheelOfFortuneSettings WheelOfFortune { get; set; }
[Comment(@"Settings related to waifus")] [Comment(@"Settings related to waifus")]
public WaifuConfig Waifu { get; set; } public WaifuConfig Waifu { get; set; }
[Comment(@"Amount of currency selfhosters will get PER pledged dollar CENT. [Comment(@"Amount of currency selfhosters will get PER pledged dollar CENT.
1 = 100 currency per $. Used almost exclusively on public nadeko.")] 1 = 100 currency per $. Used almost exclusively on public nadeko.")]
public decimal PatreonCurrencyPerCent { get; set; } = 1; public decimal PatreonCurrencyPerCent { get; set; } = 1;
}
public class CurrencyConfig public class CurrencyConfig
{ {
@@ -64,7 +70,8 @@ Set 0 for unlimited")]
public string Name { get; set; } = "Nadeko Flower"; public string Name { get; set; } = "Nadeko Flower";
} }
public class TimelyConfig [Cloneable]
public partial class TimelyConfig
{ {
[Comment(@"How much currency will the users get every time they run .timely command [Comment(@"How much currency will the users get every time they run .timely command
setting to 0 or less will disable this feature")] setting to 0 or less will disable this feature")]
@@ -75,50 +82,34 @@ setting to 0 or less will disable this feature")]
public int Cooldown { get; set; } = 24; public int Cooldown { get; set; } = 24;
} }
public class BetFlipConfig [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; public decimal Multiplier { get; set; } = 1.95M;
} }
public class BetRollConfig [Cloneable]
public partial class BetRollConfig
{ {
[Comment(@"When betroll is played, user will roll a number 0-100. [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. This setting will describe which multiplier is used for when the roll is higher than the given number.
Doesn't have to be ordered.")] Doesn't have to be ordered.")]
public Pair[] Pairs { get; set; } = Array.Empty<Pair>(); public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>();
public BetRollConfig() public BetRollConfig()
{ {
Pairs = new BetRollConfig.Pair[] Pairs = new BetRollPair[]
{ {
new BetRollConfig.Pair(99, 10), new BetRollPair { WhenAbove = 99, MultiplyBy = 10 },
new BetRollConfig.Pair(90, 4), new BetRollPair { WhenAbove = 90, MultiplyBy = 4 },
new BetRollConfig.Pair(66, 2) new BetRollPair { WhenAbove = 66, MultiplyBy = 2 }
}; };
} }
public class Pair
{
public int WhenAbove { get; set; }
public float MultiplyBy { get; set; }
public Pair()
{
} }
public Pair(int threshold, int multiplier) [Cloneable]
{ public partial class GenerationConfig
WhenAbove = threshold;
MultiplyBy = multiplier;
}
}
}
public class GenerationConfig
{ {
[Comment(@"when currency is generated, should it also have a random password [Comment(@"when currency is generated, should it also have a random password
associated with it which users have to type after the .pick command associated with it which users have to type after the .pick command
@@ -141,7 +132,8 @@ default is 0.02, which is 2%")]
public int MaxAmount { get; set; } = 1; public int MaxAmount { get; set; } = 1;
} }
public class DecayConfig [Cloneable]
public partial class DecayConfig
{ {
[Comment(@"Percentage of user's current currency which will be deducted every 24h. [Comment(@"Percentage of user's current currency which will be deducted every 24h.
0 - 1 (1 is 100%, 0.5 50%, 0 disabled)")] 0 - 1 (1 is 100%, 0.5 50%, 0 disabled)")]
@@ -157,7 +149,8 @@ default is 0.02, which is 2%")]
public int HourInterval { get; set; } = 24; 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.")] [Comment(@"Self-Explanatory. Has to have 8 values, otherwise the command won't work.")]
public decimal[] Multipliers { get; set; } public decimal[] Multipliers { get; set; }
@@ -178,10 +171,12 @@ default is 0.02, which is 2%")]
} }
} }
public class WaifuConfig [Cloneable]
public sealed partial class WaifuConfig
{ {
[Comment(@"Minimum price a waifu can have")] [Comment(@"Minimum price a waifu can have")]
public int MinPrice { get; set; } = 50; public int MinPrice { get; set; } = 50;
public MultipliersData Multipliers { get; set; } = new MultipliersData(); public MultipliersData Multipliers { get; set; } = new MultipliersData();
[Comment(@"List of items available for gifting.")] [Comment(@"List of items available for gifting.")]
@@ -189,49 +184,50 @@ default is 0.02, which is 2%")]
public WaifuConfig() public WaifuConfig()
{ {
Items = new List<WaifuItemModel>() Items = new()
{ {
new WaifuItemModel("🥔", 5, "Potato"), new("🥔", 5, "Potato"),
new WaifuItemModel("🍪", 10, "Cookie"), new("🍪", 10, "Cookie"),
new WaifuItemModel("🥖", 20, "Bread"), new("🥖", 20, "Bread"),
new WaifuItemModel("🍭", 30, "Lollipop"), new("🍭", 30, "Lollipop"),
new WaifuItemModel("🌹", 50, "Rose"), new("🌹", 50, "Rose"),
new WaifuItemModel("🍺", 70, "Beer"), new("🍺", 70, "Beer"),
new WaifuItemModel("🌮", 85, "Taco"), new("🌮", 85, "Taco"),
new WaifuItemModel("💌", 100, "LoveLetter"), new("💌", 100, "LoveLetter"),
new WaifuItemModel("🥛", 125, "Milk"), new("🥛", 125, "Milk"),
new WaifuItemModel("🍕", 150, "Pizza"), new("🍕", 150, "Pizza"),
new WaifuItemModel("🍫", 200, "Chocolate"), new("🍫", 200, "Chocolate"),
new WaifuItemModel("🍦", 250, "Icecream"), new("🍦", 250, "Icecream"),
new WaifuItemModel("🍣", 300, "Sushi"), new("🍣", 300, "Sushi"),
new WaifuItemModel("🍚", 400, "Rice"), new("🍚", 400, "Rice"),
new WaifuItemModel("🍉", 500, "Watermelon"), new("🍉", 500, "Watermelon"),
new WaifuItemModel("🍱", 600, "Bento"), new("🍱", 600, "Bento"),
new WaifuItemModel("🎟", 800, "MovieTicket"), new("🎟", 800, "MovieTicket"),
new WaifuItemModel("🍰", 1000, "Cake"), new("🍰", 1000, "Cake"),
new WaifuItemModel("📔", 1500, "Book"), new("📔", 1500, "Book"),
new WaifuItemModel("🐱", 2000, "Cat"), new("🐱", 2000, "Cat"),
new WaifuItemModel("🐶", 2001, "Dog"), new("🐶", 2001, "Dog"),
new WaifuItemModel("🐼", 2500, "Panda"), new("🐼", 2500, "Panda"),
new WaifuItemModel("💄", 3000, "Lipstick"), new("💄", 3000, "Lipstick"),
new WaifuItemModel("👛", 3500, "Purse"), new("👛", 3500, "Purse"),
new WaifuItemModel("📱", 4000, "iPhone"), new("📱", 4000, "iPhone"),
new WaifuItemModel("👗", 4500, "Dress"), new("👗", 4500, "Dress"),
new WaifuItemModel("💻", 5000, "Laptop"), new("💻", 5000, "Laptop"),
new WaifuItemModel("🎻", 7500, "Violin"), new("🎻", 7500, "Violin"),
new WaifuItemModel("🎹", 8000, "Piano"), new("🎹", 8000, "Piano"),
new WaifuItemModel("🚗", 9000, "Car"), new("🚗", 9000, "Car"),
new WaifuItemModel("💍", 10000, "Ring"), new("💍", 10000, "Ring"),
new WaifuItemModel("🛳", 12000, "Ship"), new("🛳", 12000, "Ship"),
new WaifuItemModel("🏠", 15000, "House"), new("🏠", 15000, "House"),
new WaifuItemModel("🚁", 20000, "Helicopter"), new("🚁", 20000, "Helicopter"),
new WaifuItemModel("🚀", 30000, "Spaceship"), new("🚀", 30000, "Spaceship"),
new WaifuItemModel("🌕", 50000, "Moon") new("🌕", 50000, "Moon")
}; };
} }
}
[Cloneable]
public class MultipliersData public sealed partial class MultipliersData
{ {
[Comment(@"Multiplier for waifureset. Default 150. [Comment(@"Multiplier for waifureset. Default 150.
Formula (at the time of writing this): Formula (at the time of writing this):
@@ -265,15 +261,12 @@ 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)")] 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 string ItemEmoji { get; set; }
public int Price { get; set; } public int Price { get; set; }
public string Name { get; set; } public string Name { get; set; }
public WaifuItemModel() public WaifuItemModel()
@@ -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; public override string ToString() => Name;
} }
[Cloneable]
public sealed partial class BetRollPair
{
public int WhenAbove { get; set; }
public float MultiplyBy { get; set; }
}
} }

View File

@@ -511,7 +511,7 @@ namespace NadekoBot.Modules.Gambling.Services
public IReadOnlyList<WaifuItemModel> GetWaifuItems() public IReadOnlyList<WaifuItemModel> GetWaifuItems()
{ {
var conf = _gss.Data; 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)) .Select(x => new WaifuItemModel(x.ItemEmoji, (int)(x.Price * conf.Waifu.Multipliers.AllGiftPrices), x.Name))
.ToList(); .ToList();
} }

View File

@@ -1,9 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using Cloneable;
using NadekoBot.Common;
using NadekoBot.Common.Yml; using NadekoBot.Common.Yml;
namespace NadekoBot.Modules.Games.Common namespace NadekoBot.Modules.Games.Common
{ {
public sealed class GamesConfig [Cloneable]
public sealed partial class GamesConfig : ICloneable<GamesConfig>
{ {
[Comment("Trivia related settings (.t command)")] [Comment("Trivia related settings (.t command)")]
public TriviaConfig Trivia { get; set; } = new TriviaConfig() public TriviaConfig Trivia { get; set; } = new TriviaConfig()
@@ -43,18 +46,19 @@ namespace NadekoBot.Modules.Games.Common
[Comment("List of animals which will be used for the animal race game (.race)")] [Comment("List of animals which will be used for the animal race game (.race)")]
public List<RaceAnimal> RaceAnimals { get; set; } = new List<RaceAnimal>() public List<RaceAnimal> RaceAnimals { get; set; } = new List<RaceAnimal>()
{ {
new RaceAnimal {Icon = "🐼", Name = "Panda"}, new RaceAnimal { Icon = "🐼", Name = "Panda" },
new RaceAnimal {Icon = "🐻", Name = "Bear"}, new RaceAnimal { Icon = "🐻", Name = "Bear" },
new RaceAnimal {Icon = "🐧", Name = "Pengu"}, new RaceAnimal { Icon = "🐧", Name = "Pengu" },
new RaceAnimal {Icon = "🐨", Name = "Koala"}, new RaceAnimal { Icon = "🐨", Name = "Koala" },
new RaceAnimal {Icon = "🐬", Name = "Dolphin"}, new RaceAnimal { Icon = "🐬", Name = "Dolphin" },
new RaceAnimal {Icon = "🐞", Name = "Ladybird"}, new RaceAnimal { Icon = "🐞", Name = "Ladybird" },
new RaceAnimal {Icon = "🦀", Name = "Crab"}, new RaceAnimal { Icon = "🦀", Name = "Crab" },
new RaceAnimal {Icon = "🦄", Name = "Unicorn"} 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.")] [Comment("The amount of currency awarded to the winner of the trivia game.")]
public long CurrencyReward { get; set; } = 0; 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 int MinimumWinReq { get; set; } = 1;
} }
public sealed class RaceAnimal [Cloneable]
public sealed partial class RaceAnimal
{ {
public string Icon { get; set; } public string Icon { get; set; }
public string Name { get; set; } public string Name { get; set; }

View File

@@ -34,8 +34,8 @@ namespace NadekoBot.Modules.Help.Services
_rep = new ReplacementBuilder() _rep = new ReplacementBuilder()
.WithOverride("%prefix%", () => _bss.GetRawData().Prefix) .WithOverride("%prefix%", () => _bss.Data.Prefix)
.WithOverride("%bot.prefix%", () => _bss.GetRawData().Prefix) .WithOverride("%bot.prefix%", () => _bss.Data.Prefix)
.Build(); .Build();
} }

View File

@@ -1,8 +1,11 @@
using NadekoBot.Common.Yml; using Cloneable;
using NadekoBot.Common;
using NadekoBot.Common.Yml;
namespace NadekoBot.Modules.Xp namespace NadekoBot.Modules.Xp
{ {
public sealed class XpConfig [Cloneable]
public sealed partial class XpConfig : ICloneable<XpConfig>
{ {
[Comment(@"DO NOT CHANGE")] [Comment(@"DO NOT CHANGE")]
public int Version { get; set; } = 2; public int Version { get; set; } = 2;

View File

@@ -623,15 +623,16 @@ namespace NadekoBot.Modules.Xp.Services
if (!ShouldTrackXp(user, arg.Channel.Id)) if (!ShouldTrackXp(user, arg.Channel.Id))
return; return;
var xpConf = _xpConfig.Data;
var xp = 0; var xp = 0;
if (arg.Attachments.Any(a => a.Height >= 128 && a.Width >= 128)) 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) if (arg.Content.Contains(' ') || arg.Content.Length >= 5)
{ {
xp = Math.Max(xp, _xpConfig.GetRawData().XpPerMessage); xp = Math.Max(xp, xpConf.XpPerMessage);
} }
if (xp <= 0) if (xp <= 0)

View File

@@ -11,6 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp" Version="0.16.0" /> <PackageReference Include="AngleSharp" Version="0.16.0" />
<PackageReference Include="AWSSDK.S3" Version="3.7.1.4" /> <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="CodeHollow.FeedReader" Version="1.2.1" />
<PackageReference Include="CommandLineParser" Version="2.8.0" /> <PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="Discord.Net" Version="2.4.0" /> <PackageReference Include="Discord.Net" Version="2.4.0" />

View File

@@ -142,7 +142,7 @@ namespace NadekoBot.Services
private Task LogSuccessfulExecution(IUserMessage usrMsg, ITextChannel channel, params int[] execPoints) 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" + Log.Information($"Command Executed after " + string.Join("/", execPoints.Select(x => (x * _oneThousandth).ToString("F3"))) + "s\n\t" +
"User: {0}\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) 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" + Log.Warning($"Command Errored after " + string.Join("/", execPoints.Select(x => (x * _oneThousandth).ToString("F3"))) + "s\n\t" +
"User: {0}\n\t" + "User: {0}\n\t" +

View File

@@ -83,7 +83,7 @@ namespace NadekoBot.Services
.EmbedAsync(new EmbedBuilder() .EmbedAsync(new EmbedBuilder()
.WithOkColor() .WithOkColor()
.WithTitle($"Received Currency") .WithTitle($"Received Currency")
.AddField("Amount", amount + _gss.Data.Currency.Sign) .AddField("Amount", amount + sign)
.AddField("Reason", reason)); .AddField("Reason", reason));
} }
catch catch

View File

@@ -4,14 +4,10 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Common.Yml; using NadekoBot.Common.Yml;
using NadekoBot.Common; using NadekoBot.Common;
using NadekoBot.Common.Configs; using NadekoBot.Common.Configs;
using NadekoBot.Common.JsonConverters;
using Rgba32Converter = NadekoBot.Common.JsonConverters.Rgba32Converter;
using CultureInfoConverter = NadekoBot.Common.JsonConverters.CultureInfoConverter;
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
@@ -20,7 +16,7 @@ namespace NadekoBot.Services
/// </summary> /// </summary>
/// <typeparam name="TSettings">Type of the settings</typeparam> /// <typeparam name="TSettings">Type of the settings</typeparam>
public abstract class ConfigServiceBase<TSettings> : IConfigService public abstract class ConfigServiceBase<TSettings> : IConfigService
where TSettings : new() where TSettings : ICloneable<TSettings>, new()
{ {
protected readonly string _filePath; protected readonly string _filePath;
protected readonly IConfigSeria _serializer; protected readonly IConfigSeria _serializer;
@@ -29,8 +25,8 @@ namespace NadekoBot.Services
protected TSettings _data; protected TSettings _data;
// todo this has to be protected from mutation // todo future config arrays are not copied - they're not protected from mutations
public TSettings Data => _data; public TSettings Data => _data.Clone();
public abstract string Name { get; } public abstract string Name { get; }
@@ -65,21 +61,6 @@ namespace NadekoBot.Services
return default; 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> /// <summary>
/// Loads data from disk. If file doesn't exist, it will be created with default values /// Loads data from disk. If file doesn't exist, it will be created with default values
/// </summary> /// </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() private void Save()
{ {
var strData = _serializer.Serialize(_data); var strData = _serializer.Serialize(_data);
@@ -162,9 +135,7 @@ namespace NadekoBot.Services
var expr = (MemberExpression)selector.Body; var expr = (MemberExpression)selector.Body;
var prop = (PropertyInfo)expr.Member; var prop = (PropertyInfo)expr.Member;
var expressions = new List<MemberExpression>() var expressions = new List<MemberExpression>();
{
};
while (true) while (true)
{ {
@@ -224,6 +195,13 @@ namespace NadekoBot.Services
return success; return success;
} }
public TSettings GetRawData() => _data; public void ModifyConfig(Action<TSettings> action)
{
var copy = Data;
action(copy);
_data = copy;
Save();
PublishChange();
}
} }
} }