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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var random = _randomNumberGenerator.Next(0, s.Count);
|
var random = _randomNumberGenerator.Next(0, s.Count - 1);
|
||||||
var quote = s[random];
|
var quote = s[random];
|
||||||
|
|
||||||
var embed = QuoteBuilder(quote);
|
var embed = QuoteBuilder(quote);
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace Geekbot.Bot
|
||||||
var emojiConverter = new EmojiConverter();
|
var emojiConverter = new EmojiConverter();
|
||||||
var mtgManaConverter = new MtgManaConverter();
|
var mtgManaConverter = new MtgManaConverter();
|
||||||
var wikipediaClient = new WikipediaClient();
|
var wikipediaClient = new WikipediaClient();
|
||||||
var randomNumberGenerator = new RandomNumberGenerator();
|
var randomNumberGenerator = new RandomNumberGenerator(_globalSettings);
|
||||||
var mediaProvider = new MediaProvider(_logger, randomNumberGenerator);
|
var mediaProvider = new MediaProvider(_logger, randomNumberGenerator);
|
||||||
var kvMemoryStore = new KvInInMemoryStore();
|
var kvMemoryStore = new KvInInMemoryStore();
|
||||||
var errorHandler = new ErrorHandler(_logger, _runParameters, () => Localization.Internal.SomethingWentWrong);
|
var errorHandler = new ErrorHandler(_logger, _runParameters, () => Localization.Internal.SomethingWentWrong);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Anemonis.RandomOrg" Version="1.14.0" />
|
||||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||||
<PackageReference Include="Discord.Net" Version="2.2.0" />
|
<PackageReference Include="Discord.Net" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0-rc.1.*" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0-rc.1.*" />
|
||||||
|
|
|
@ -1,25 +1,69 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using Anemonis.RandomOrg;
|
||||||
|
using Geekbot.Core.GlobalSettings;
|
||||||
|
|
||||||
namespace Geekbot.Core.RandomNumberGenerator
|
namespace Geekbot.Core.RandomNumberGenerator
|
||||||
{
|
{
|
||||||
public class RandomNumberGenerator : IRandomNumberGenerator
|
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();
|
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");
|
throw new ArgumentOutOfRangeException("minValue must be lower than maxExclusiveValue");
|
||||||
}
|
}
|
||||||
|
|
||||||
var diff = (long)maxExclusiveValue - minValue;
|
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;
|
var upperBound = uint.MaxValue / diff * diff;
|
||||||
|
|
||||||
uint ui;
|
uint ui;
|
||||||
|
@ -27,7 +71,8 @@ namespace Geekbot.Core.RandomNumberGenerator
|
||||||
{
|
{
|
||||||
ui = GetRandomUInt();
|
ui = GetRandomUInt();
|
||||||
} while (ui >= upperBound);
|
} while (ui >= upperBound);
|
||||||
return (int)(minValue + (ui % diff));
|
|
||||||
|
return (int) (minValue + (ui % diff));
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint GetRandomUInt()
|
private uint GetRandomUInt()
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Geekbot.Core.DiceParser;
|
using Geekbot.Core.DiceParser;
|
||||||
|
using Geekbot.Core.GlobalSettings;
|
||||||
using Geekbot.Core.RandomNumberGenerator;
|
using Geekbot.Core.RandomNumberGenerator;
|
||||||
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Tests.Core.DiceParser
|
namespace Tests.Core.DiceParser
|
||||||
{
|
{
|
||||||
public class DiceParserTest
|
public class DiceParserTest
|
||||||
{
|
{
|
||||||
private static readonly RandomNumberGenerator _randomNumberGenerator = new RandomNumberGenerator();
|
private static readonly RandomNumberGenerator _randomNumberGenerator = new RandomNumberGenerator(new Mock<IGlobalSettings>().Object);
|
||||||
|
|
||||||
public struct DiceParserTestDto
|
public struct DiceParserTestDto
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Geekbot.Core.DiceParser;
|
using Geekbot.Core.DiceParser;
|
||||||
|
using Geekbot.Core.GlobalSettings;
|
||||||
using Geekbot.Core.RandomNumberGenerator;
|
using Geekbot.Core.RandomNumberGenerator;
|
||||||
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Tests.Core.DiceParser
|
namespace Tests.Core.DiceParser
|
||||||
|
@ -43,7 +45,7 @@ namespace Tests.Core.DiceParser
|
||||||
[Theory, MemberData(nameof(SingleDieNameTestData))]
|
[Theory, MemberData(nameof(SingleDieNameTestData))]
|
||||||
public void SingleDieNameTestFunc(string testName, SingleDieNameTestDto testData)
|
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);
|
Assert.Equal(die.DiceName, testData.Expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +108,7 @@ namespace Tests.Core.DiceParser
|
||||||
[Theory, MemberData(nameof(SingleDieValidationTestData))]
|
[Theory, MemberData(nameof(SingleDieValidationTestData))]
|
||||||
public void SingleDieValidationTestFunc(string testName, SingleDieValidationTestDto testData)
|
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,
|
Amount = testData.Amount,
|
||||||
Sides = testData.Sides
|
Sides = testData.Sides
|
||||||
|
|
Loading…
Reference in a new issue