Add random.org for random number generation.
This commit is contained in:
parent
b743539c74
commit
ae9b9caeb9
6 changed files with 62 additions and 12 deletions
|
@ -46,7 +46,7 @@ namespace Geekbot.Bot.Commands.Utils.Quote
|
|||
return;
|
||||
}
|
||||
|
||||
var random = _randomNumberGenerator.Next(0, s.Count);
|
||||
var random = _randomNumberGenerator.Next(0, s.Count - 1);
|
||||
var quote = s[random];
|
||||
|
||||
var embed = QuoteBuilder(quote);
|
||||
|
|
|
@ -164,7 +164,7 @@ namespace Geekbot.Bot
|
|||
var emojiConverter = new EmojiConverter();
|
||||
var mtgManaConverter = new MtgManaConverter();
|
||||
var wikipediaClient = new WikipediaClient();
|
||||
var randomNumberGenerator = new RandomNumberGenerator();
|
||||
var randomNumberGenerator = new RandomNumberGenerator(_globalSettings);
|
||||
var mediaProvider = new MediaProvider(_logger, randomNumberGenerator);
|
||||
var kvMemoryStore = new KvInInMemoryStore();
|
||||
var errorHandler = new ErrorHandler(_logger, _runParameters, () => Localization.Internal.SomethingWentWrong);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Anemonis.RandomOrg" Version="1.14.0" />
|
||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||
<PackageReference Include="Discord.Net" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0-rc.1.*" />
|
||||
|
|
|
@ -1,24 +1,68 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Anemonis.RandomOrg;
|
||||
using Geekbot.Core.GlobalSettings;
|
||||
|
||||
namespace Geekbot.Core.RandomNumberGenerator
|
||||
{
|
||||
public class RandomNumberGenerator : IRandomNumberGenerator
|
||||
{
|
||||
readonly RNGCryptoServiceProvider csp;
|
||||
private readonly RNGCryptoServiceProvider csp;
|
||||
private readonly bool _canUseRandomOrg;
|
||||
private readonly RandomOrgClient _randomOrgClient;
|
||||
|
||||
public RandomNumberGenerator()
|
||||
public RandomNumberGenerator(IGlobalSettings globalSettings)
|
||||
{
|
||||
csp = new RNGCryptoServiceProvider();
|
||||
|
||||
var randomOrgApiKey = globalSettings.GetKey("RandomOrgApiKey");
|
||||
if (!string.IsNullOrEmpty(randomOrgApiKey))
|
||||
{
|
||||
_canUseRandomOrg = true;
|
||||
_randomOrgClient = new RandomOrgClient(randomOrgApiKey);
|
||||
}
|
||||
}
|
||||
|
||||
public int Next(int minValue, int maxExclusiveValue)
|
||||
public int Next(int minValue, int maxInclusiveValue)
|
||||
{
|
||||
if (minValue >= maxExclusiveValue)
|
||||
if (minValue == maxInclusiveValue)
|
||||
{
|
||||
return maxInclusiveValue;
|
||||
}
|
||||
|
||||
if (minValue >= maxInclusiveValue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("minValue must be lower than maxExclusiveValue");
|
||||
}
|
||||
|
||||
if (_canUseRandomOrg)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetFromRandomOrg(minValue, maxInclusiveValue);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
return GetFromCrypto(minValue, maxInclusiveValue);
|
||||
}
|
||||
|
||||
private int GetFromRandomOrg(int minValue, int maxInclusiveValue)
|
||||
{
|
||||
return _randomOrgClient
|
||||
.GenerateIntegersAsync(1, minValue, maxInclusiveValue, false)
|
||||
.Result
|
||||
.Random
|
||||
.Data[0];
|
||||
}
|
||||
|
||||
private int GetFromCrypto(int minValue, int maxInclusiveValue)
|
||||
{
|
||||
var maxExclusiveValue = maxInclusiveValue + 1;
|
||||
|
||||
var diff = (long) maxExclusiveValue - minValue;
|
||||
var upperBound = uint.MaxValue / diff * diff;
|
||||
|
||||
|
@ -27,6 +71,7 @@ namespace Geekbot.Core.RandomNumberGenerator
|
|||
{
|
||||
ui = GetRandomUInt();
|
||||
} while (ui >= upperBound);
|
||||
|
||||
return (int) (minValue + (ui % diff));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Geekbot.Core.DiceParser;
|
||||
using Geekbot.Core.GlobalSettings;
|
||||
using Geekbot.Core.RandomNumberGenerator;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Tests.Core.DiceParser
|
||||
{
|
||||
public class DiceParserTest
|
||||
{
|
||||
private static readonly RandomNumberGenerator _randomNumberGenerator = new RandomNumberGenerator();
|
||||
private static readonly RandomNumberGenerator _randomNumberGenerator = new RandomNumberGenerator(new Mock<IGlobalSettings>().Object);
|
||||
|
||||
public struct DiceParserTestDto
|
||||
{
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using Geekbot.Core.DiceParser;
|
||||
using Geekbot.Core.GlobalSettings;
|
||||
using Geekbot.Core.RandomNumberGenerator;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Tests.Core.DiceParser
|
||||
|
@ -43,7 +45,7 @@ namespace Tests.Core.DiceParser
|
|||
[Theory, MemberData(nameof(SingleDieNameTestData))]
|
||||
public void SingleDieNameTestFunc(string testName, SingleDieNameTestDto testData)
|
||||
{
|
||||
var die = new SingleDie(new RandomNumberGenerator()) {AdvantageType = testData.AdvantageType};
|
||||
var die = new SingleDie(new RandomNumberGenerator(new Mock<IGlobalSettings>().Object)) {AdvantageType = testData.AdvantageType};
|
||||
Assert.Equal(die.DiceName, testData.Expected);
|
||||
}
|
||||
|
||||
|
@ -106,7 +108,7 @@ namespace Tests.Core.DiceParser
|
|||
[Theory, MemberData(nameof(SingleDieValidationTestData))]
|
||||
public void SingleDieValidationTestFunc(string testName, SingleDieValidationTestDto testData)
|
||||
{
|
||||
var die = new SingleDie(new RandomNumberGenerator())
|
||||
var die = new SingleDie(new RandomNumberGenerator(new Mock<IGlobalSettings>().Object))
|
||||
{
|
||||
Amount = testData.Amount,
|
||||
Sides = testData.Sides
|
||||
|
|
Loading…
Reference in a new issue