- 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>());
}
// todo no public bot attribute
svcs.Scan(scan => scan
.FromAssemblyOf<IReadyExecutor>()
.AddClasses(classes => classes.AssignableToAny(

View File

@@ -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,

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)
{
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})";

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

View File

@@ -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; }
}
}

View File

@@ -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();
}

View File

@@ -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; }

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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" />

View File

@@ -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" +

View File

@@ -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

View File

@@ -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();
}
}
}