Add a better random number generator

This commit is contained in:
runebaas 2019-05-11 01:18:22 +02:00
parent fe08eee049
commit 4143180b42
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
8 changed files with 85 additions and 9 deletions

View file

@ -8,6 +8,7 @@ using Geekbot.net.Lib.AlmostRedis;
using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.ErrorHandling;
using Geekbot.net.Lib.Extensions; using Geekbot.net.Lib.Extensions;
using Geekbot.net.Lib.Localization; using Geekbot.net.Lib.Localization;
using Geekbot.net.Lib.RandomNumberGenerator;
using StackExchange.Redis; using StackExchange.Redis;
namespace Geekbot.net.Commands.Games namespace Geekbot.net.Commands.Games
@ -18,12 +19,14 @@ namespace Geekbot.net.Commands.Games
private readonly IAlmostRedis _redis; private readonly IAlmostRedis _redis;
private readonly ITranslationHandler _translation; private readonly ITranslationHandler _translation;
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
private readonly IRandomNumberGenerator _randomNumberGenerator;
public Roll(IAlmostRedis redis, IErrorHandler errorHandler, ITranslationHandler translation, DatabaseContext database) public Roll(IAlmostRedis redis, IErrorHandler errorHandler, ITranslationHandler translation, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator)
{ {
_redis = redis; _redis = redis;
_translation = translation; _translation = translation;
_database = database; _database = database;
_randomNumberGenerator = randomNumberGenerator;
_errorHandler = errorHandler; _errorHandler = errorHandler;
} }
@ -33,7 +36,7 @@ namespace Geekbot.net.Commands.Games
{ {
try try
{ {
var number = new Random().Next(1, 100); var number = _randomNumberGenerator.Next(1, 100);
var guess = 1000; var guess = 1000;
int.TryParse(stuff, out guess); int.TryParse(stuff, out guess);
var transDict = await _translation.GetDict(Context); var transDict = await _translation.GetDict(Context);

View file

@ -7,18 +7,21 @@ using Geekbot.net.Database;
using Geekbot.net.Database.Models; using Geekbot.net.Database.Models;
using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.ErrorHandling;
using Geekbot.net.Lib.Extensions; using Geekbot.net.Lib.Extensions;
using Geekbot.net.Lib.RandomNumberGenerator;
namespace Geekbot.net.Commands.Randomness namespace Geekbot.net.Commands.Randomness
{ {
public class Ship : ModuleBase public class Ship : ModuleBase
{ {
private readonly IErrorHandler _errorHandler; private readonly IErrorHandler _errorHandler;
private readonly IRandomNumberGenerator _randomNumberGenerator;
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
public Ship(DatabaseContext database, IErrorHandler errorHandler) public Ship(DatabaseContext database, IErrorHandler errorHandler, IRandomNumberGenerator randomNumberGenerator)
{ {
_database = database; _database = database;
_errorHandler = errorHandler; _errorHandler = errorHandler;
_randomNumberGenerator = randomNumberGenerator;
} }
[Command("Ship", RunMode = RunMode.Async)] [Command("Ship", RunMode = RunMode.Async)]
@ -38,7 +41,7 @@ namespace Geekbot.net.Commands.Randomness
var shippingRate = 0; var shippingRate = 0;
if (dbval == null) if (dbval == null)
{ {
shippingRate = new Random().Next(1, 100); shippingRate = _randomNumberGenerator.Next(1, 100);
_database.Ships.Add(new ShipsModel() _database.Ships.Add(new ShipsModel()
{ {
FirstUserId = userKeys.Item1, FirstUserId = userKeys.Item1,

View file

@ -9,6 +9,7 @@ using Geekbot.net.Lib.CommandPreconditions;
using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.ErrorHandling;
using Geekbot.net.Lib.Extensions; using Geekbot.net.Lib.Extensions;
using Geekbot.net.Lib.Localization; using Geekbot.net.Lib.Localization;
using Geekbot.net.Lib.RandomNumberGenerator;
namespace Geekbot.net.Commands.Rpg namespace Geekbot.net.Commands.Rpg
{ {
@ -19,12 +20,14 @@ namespace Geekbot.net.Commands.Rpg
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
private readonly IErrorHandler _errorHandler; private readonly IErrorHandler _errorHandler;
private readonly ITranslationHandler _translation; private readonly ITranslationHandler _translation;
private readonly IRandomNumberGenerator _randomNumberGenerator;
public Cookies(DatabaseContext database, IErrorHandler errorHandler, ITranslationHandler translation) public Cookies(DatabaseContext database, IErrorHandler errorHandler, ITranslationHandler translation , IRandomNumberGenerator randomNumberGenerator)
{ {
_database = database; _database = database;
_errorHandler = errorHandler; _errorHandler = errorHandler;
_translation = translation; _translation = translation;
_randomNumberGenerator = randomNumberGenerator;
} }
[Command("get", RunMode = RunMode.Async)] [Command("get", RunMode = RunMode.Async)]
@ -114,7 +117,7 @@ namespace Geekbot.net.Commands.Rpg
return; return;
} }
var amount = new Random().Next(1, 5); var amount = _randomNumberGenerator.Next(1, 5);
actor.Cookies -= amount; actor.Cookies -= amount;
await SetUser(actor); await SetUser(actor);

View file

@ -4,11 +4,19 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands; using Discord.Commands;
using Geekbot.net.Lib.RandomNumberGenerator;
namespace Geekbot.net.Commands.Utils.Dice namespace Geekbot.net.Commands.Utils.Dice
{ {
public class Dice : ModuleBase public class Dice : ModuleBase
{ {
private readonly IRandomNumberGenerator _randomNumberGenerator;
public Dice(IRandomNumberGenerator randomNumberGenerator)
{
_randomNumberGenerator = randomNumberGenerator;
}
[Command("dice", RunMode = RunMode.Async)] [Command("dice", RunMode = RunMode.Async)]
[Summary("Roll a dice.")] [Summary("Roll a dice.")]
public async Task RollCommand([Remainder] [Summary("diceType")] string diceType = "1d20") public async Task RollCommand([Remainder] [Summary("diceType")] string diceType = "1d20")
@ -66,7 +74,7 @@ namespace Geekbot.net.Commands.Utils.Dice
var results = new List<int>(); var results = new List<int>();
for (var i = 0; i < dice.Times; i++) for (var i = 0; i < dice.Times; i++)
{ {
var roll = new Random().Next(1, dice.Sides); var roll = _randomNumberGenerator.Next(1, dice.Sides);
total += roll; total += roll;
results.Add(roll); results.Add(roll);
if (roll == dice.Sides) extraText = "**Critical Hit!**"; if (roll == dice.Sides) extraText = "**Critical Hit!**";

View file

@ -9,6 +9,7 @@ using Geekbot.net.Lib.CommandPreconditions;
using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.ErrorHandling;
using Geekbot.net.Lib.Extensions; using Geekbot.net.Lib.Extensions;
using Geekbot.net.Lib.Polyfills; using Geekbot.net.Lib.Polyfills;
using Geekbot.net.Lib.RandomNumberGenerator;
namespace Geekbot.net.Commands.Utils.Quote namespace Geekbot.net.Commands.Utils.Quote
{ {
@ -18,11 +19,13 @@ namespace Geekbot.net.Commands.Utils.Quote
{ {
private readonly IErrorHandler _errorHandler; private readonly IErrorHandler _errorHandler;
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
private readonly IRandomNumberGenerator _randomNumberGenerator;
public Quote(IErrorHandler errorHandler, DatabaseContext database) public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator)
{ {
_errorHandler = errorHandler; _errorHandler = errorHandler;
_database = database; _database = database;
_randomNumberGenerator = randomNumberGenerator;
} }
[Command] [Command]
@ -39,7 +42,7 @@ namespace Geekbot.net.Commands.Utils.Quote
return; return;
} }
var random = new Random().Next(s.Count()); var random = _randomNumberGenerator.Next(0, s.Count());
var quote = s[random]; var quote = s[random];
var embed = QuoteBuilder(quote); var embed = QuoteBuilder(quote);

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Lib.RandomNumberGenerator
{
public interface IRandomNumberGenerator
{
int Next(int minValue, int maxExclusiveValue);
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Security.Cryptography;
namespace Geekbot.net.Lib.RandomNumberGenerator
{
public class RandomNumberGenerator : IRandomNumberGenerator
{
readonly RNGCryptoServiceProvider csp;
public RandomNumberGenerator()
{
csp = new RNGCryptoServiceProvider();
}
public int Next(int minValue, int maxExclusiveValue)
{
if (minValue >= maxExclusiveValue)
{
throw new ArgumentOutOfRangeException("minValue must be lower than maxExclusiveValue");
}
var diff = (long)maxExclusiveValue - minValue;
var upperBound = uint.MaxValue / diff * diff;
uint ui;
do
{
ui = GetRandomUInt();
} while (ui >= upperBound);
return (int)(minValue + (ui % diff));
}
private uint GetRandomUInt()
{
var randomBytes = GenerateRandomBytes(sizeof(uint));
return BitConverter.ToUInt32(randomBytes, 0);
}
private byte[] GenerateRandomBytes(int bytesNumber)
{
var buffer = new byte[bytesNumber];
csp.GetBytes(buffer);
return buffer;
}
}
}

View file

@ -19,6 +19,7 @@ using Geekbot.net.Lib.Levels;
using Geekbot.net.Lib.Localization; using Geekbot.net.Lib.Localization;
using Geekbot.net.Lib.Logger; using Geekbot.net.Lib.Logger;
using Geekbot.net.Lib.Media; using Geekbot.net.Lib.Media;
using Geekbot.net.Lib.RandomNumberGenerator;
using Geekbot.net.Lib.ReactionListener; using Geekbot.net.Lib.ReactionListener;
using Geekbot.net.Lib.UserRepository; using Geekbot.net.Lib.UserRepository;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -124,6 +125,7 @@ namespace Geekbot.net
var mtgManaConverter = new MtgManaConverter(); var mtgManaConverter = new MtgManaConverter();
var wikipediaClient = new WikipediaClient(); var wikipediaClient = new WikipediaClient();
var audioUtils = new AudioUtils(); var audioUtils = new AudioUtils();
var randomNumberGenerator = new RandomNumberGenerator();
_highscoreManager = new HighscoreManager(_databaseInitializer.Initialize(), _userRepository); _highscoreManager = new HighscoreManager(_databaseInitializer.Initialize(), _userRepository);
_services.AddSingleton<IAlmostRedis>(_redis); _services.AddSingleton<IAlmostRedis>(_redis);
@ -137,6 +139,7 @@ namespace Geekbot.net
_services.AddSingleton<IMtgManaConverter>(mtgManaConverter); _services.AddSingleton<IMtgManaConverter>(mtgManaConverter);
_services.AddSingleton<IWikipediaClient>(wikipediaClient); _services.AddSingleton<IWikipediaClient>(wikipediaClient);
_services.AddSingleton<IAudioUtils>(audioUtils); _services.AddSingleton<IAudioUtils>(audioUtils);
_services.AddSingleton<IRandomNumberGenerator>(randomNumberGenerator);
_services.AddSingleton<IHighscoreManager>(_highscoreManager); _services.AddSingleton<IHighscoreManager>(_highscoreManager);
_services.AddSingleton<IGlobalSettings>(_globalSettings); _services.AddSingleton<IGlobalSettings>(_globalSettings);
_services.AddTransient<DatabaseContext>((e) => _databaseInitializer.Initialize()); _services.AddTransient<DatabaseContext>((e) => _databaseInitializer.Initialize());