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.Extensions;
using Geekbot.net.Lib.Localization;
using Geekbot.net.Lib.RandomNumberGenerator;
using StackExchange.Redis;
namespace Geekbot.net.Commands.Games
@ -18,12 +19,14 @@ namespace Geekbot.net.Commands.Games
private readonly IAlmostRedis _redis;
private readonly ITranslationHandler _translation;
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;
_translation = translation;
_database = database;
_randomNumberGenerator = randomNumberGenerator;
_errorHandler = errorHandler;
}
@ -33,7 +36,7 @@ namespace Geekbot.net.Commands.Games
{
try
{
var number = new Random().Next(1, 100);
var number = _randomNumberGenerator.Next(1, 100);
var guess = 1000;
int.TryParse(stuff, out guess);
var transDict = await _translation.GetDict(Context);

View file

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

View file

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

View file

@ -4,11 +4,19 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using Geekbot.net.Lib.RandomNumberGenerator;
namespace Geekbot.net.Commands.Utils.Dice
{
public class Dice : ModuleBase
{
private readonly IRandomNumberGenerator _randomNumberGenerator;
public Dice(IRandomNumberGenerator randomNumberGenerator)
{
_randomNumberGenerator = randomNumberGenerator;
}
[Command("dice", RunMode = RunMode.Async)]
[Summary("Roll a dice.")]
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>();
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;
results.Add(roll);
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.Extensions;
using Geekbot.net.Lib.Polyfills;
using Geekbot.net.Lib.RandomNumberGenerator;
namespace Geekbot.net.Commands.Utils.Quote
{
@ -18,11 +19,13 @@ namespace Geekbot.net.Commands.Utils.Quote
{
private readonly IErrorHandler _errorHandler;
private readonly DatabaseContext _database;
private readonly IRandomNumberGenerator _randomNumberGenerator;
public Quote(IErrorHandler errorHandler, DatabaseContext database)
public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator)
{
_errorHandler = errorHandler;
_database = database;
_randomNumberGenerator = randomNumberGenerator;
}
[Command]
@ -39,7 +42,7 @@ namespace Geekbot.net.Commands.Utils.Quote
return;
}
var random = new Random().Next(s.Count());
var random = _randomNumberGenerator.Next(0, s.Count());
var quote = s[random];
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.Logger;
using Geekbot.net.Lib.Media;
using Geekbot.net.Lib.RandomNumberGenerator;
using Geekbot.net.Lib.ReactionListener;
using Geekbot.net.Lib.UserRepository;
using Microsoft.EntityFrameworkCore;
@ -124,6 +125,7 @@ namespace Geekbot.net
var mtgManaConverter = new MtgManaConverter();
var wikipediaClient = new WikipediaClient();
var audioUtils = new AudioUtils();
var randomNumberGenerator = new RandomNumberGenerator();
_highscoreManager = new HighscoreManager(_databaseInitializer.Initialize(), _userRepository);
_services.AddSingleton<IAlmostRedis>(_redis);
@ -137,6 +139,7 @@ namespace Geekbot.net
_services.AddSingleton<IMtgManaConverter>(mtgManaConverter);
_services.AddSingleton<IWikipediaClient>(wikipediaClient);
_services.AddSingleton<IAudioUtils>(audioUtils);
_services.AddSingleton<IRandomNumberGenerator>(randomNumberGenerator);
_services.AddSingleton<IHighscoreManager>(_highscoreManager);
_services.AddSingleton<IGlobalSettings>(_globalSettings);
_services.AddTransient<DatabaseContext>((e) => _databaseInitializer.Initialize());