Fixed memory leak, trivia hints are after 6 sec, etc
This commit is contained in:
@@ -5,27 +5,31 @@ using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
using Discord.Commands;
|
||||
using Discord;
|
||||
using Discord.Legacy;
|
||||
using NadekoBot.Modules;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
|
||||
namespace NadekoBot.Extensions
|
||||
{
|
||||
namespace NadekoBot.Extensions {
|
||||
public static class Extensions
|
||||
{
|
||||
public static string Scramble(this string word) {
|
||||
|
||||
var letters = word.ToArray();
|
||||
for (int i = 0; i < letters.Length; i++)
|
||||
{
|
||||
if (i % 3 == 0)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < letters.Length; i++) {
|
||||
if (letters[i] == ' ')
|
||||
continue;
|
||||
|
||||
count++;
|
||||
if (count <= letters.Length / 5)
|
||||
continue;
|
||||
|
||||
if (count % 3 == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (letters[i] != ' ')
|
||||
letters[i] = '_';
|
||||
|
||||
}
|
||||
return "`"+string.Join(" ", letters)+"`";
|
||||
}
|
||||
|
@@ -15,13 +15,15 @@ namespace NadekoBot.Classes.Music {
|
||||
public StreamRequest CurrentSong;
|
||||
|
||||
public bool IsPaused { get; internal set; } = false;
|
||||
public bool Stopped { get; private set; }
|
||||
|
||||
public IAudioClient VoiceClient;
|
||||
|
||||
private readonly object _voiceLock = new object();
|
||||
|
||||
public MusicControls() {
|
||||
Task.Run(async () => {
|
||||
while (true) {
|
||||
while (!Stopped) {
|
||||
try {
|
||||
lock (_voiceLock) {
|
||||
if (CurrentSong == null) {
|
||||
@@ -36,7 +38,7 @@ namespace NadekoBot.Classes.Music {
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine("Bug in music task run. " + e);
|
||||
}
|
||||
await Task.Delay(200);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -52,7 +54,11 @@ namespace NadekoBot.Classes.Music {
|
||||
if (SongQueue.Count != 0) {
|
||||
CurrentSong = SongQueue[0];
|
||||
SongQueue.RemoveAt(0);
|
||||
} else return;
|
||||
} else {
|
||||
VoiceClient?.Disconnect();
|
||||
VoiceClient = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -60,32 +66,35 @@ namespace NadekoBot.Classes.Music {
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine($"Starting failed: {ex}");
|
||||
CurrentSong?.Stop();
|
||||
CurrentSong = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Stop() {
|
||||
lock (_voiceLock) {
|
||||
Stopped = true;
|
||||
foreach (var kvp in SongQueue) {
|
||||
if(kvp != null)
|
||||
kvp.Cancel();
|
||||
}
|
||||
SongQueue?.Clear();
|
||||
LoadNextSong();
|
||||
SongQueue.Clear();
|
||||
CurrentSong?.Stop();
|
||||
CurrentSong = null;
|
||||
VoiceClient?.Disconnect();
|
||||
VoiceClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal StreamRequest CreateStreamRequest(CommandEventArgs e, string query, Channel voiceChannel) {
|
||||
internal async Task<StreamRequest> CreateStreamRequest(CommandEventArgs e, string query, Channel voiceChannel) {
|
||||
if (VoiceChannel == null)
|
||||
throw new ArgumentNullException("Please join a voicechannel.");
|
||||
StreamRequest sr = null;
|
||||
if (VoiceClient == null) {
|
||||
VoiceChannel = voiceChannel;
|
||||
VoiceClient = await NadekoBot.client.Audio().Join(VoiceChannel);
|
||||
}
|
||||
sr = new StreamRequest(e, query, this);
|
||||
|
||||
lock (_voiceLock) {
|
||||
if (VoiceClient == null) {
|
||||
VoiceClient = NadekoBot.client.Audio().Join(VoiceChannel).Result;
|
||||
}
|
||||
sr = new StreamRequest(e, query, this);
|
||||
SongQueue.Add(sr);
|
||||
}
|
||||
return sr;
|
||||
|
@@ -6,13 +6,13 @@ using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Audio;
|
||||
using YoutubeExtractor;
|
||||
using NadekoBot.Modules;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Threading;
|
||||
using Timer = System.Timers.Timer;
|
||||
using YoutubeExtractor;
|
||||
|
||||
namespace NadekoBot.Classes.Music {
|
||||
public enum StreamState {
|
||||
@@ -94,12 +94,12 @@ namespace NadekoBot.Classes.Music {
|
||||
musicStreamer?.Stop();
|
||||
}
|
||||
|
||||
internal Task Start() =>
|
||||
Task.Run(async () => {
|
||||
Console.WriteLine("Start called.");
|
||||
internal async Task Start() {
|
||||
Console.WriteLine("Start called.");
|
||||
|
||||
int attemptsLeft = 4;
|
||||
//wait for up to 4 seconds to resolve a link
|
||||
int attemptsLeft = 4;
|
||||
//wait for up to 4 seconds to resolve a link
|
||||
try {
|
||||
while (State == StreamState.Resolving) {
|
||||
await Task.Delay(1000);
|
||||
Console.WriteLine("Resolving...");
|
||||
@@ -107,13 +107,15 @@ namespace NadekoBot.Classes.Music {
|
||||
throw new TimeoutException("Resolving timed out.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
await musicStreamer.StartPlayback();
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Error in start playback." + ex.Message);
|
||||
privateState = StreamState.Completed;
|
||||
}
|
||||
});
|
||||
await musicStreamer.StartPlayback();
|
||||
} catch (TimeoutException) {
|
||||
Console.WriteLine("Resolving timed out.");
|
||||
privateState = StreamState.Completed;
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Error in start playback." + ex.Message);
|
||||
privateState = StreamState.Completed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MusicStreamer {
|
||||
@@ -127,7 +129,7 @@ namespace NadekoBot.Classes.Music {
|
||||
|
||||
StreamRequest parent;
|
||||
private readonly object _bufferLock = new object();
|
||||
private CancellationTokenSource bufferCancelSource;
|
||||
private bool prebufferingComplete = false;
|
||||
|
||||
public MusicStreamer(StreamRequest parent, string directUrl, Channel channel) {
|
||||
this.parent = parent;
|
||||
@@ -136,7 +138,6 @@ namespace NadekoBot.Classes.Music {
|
||||
this.Url = directUrl;
|
||||
Console.WriteLine("Created new streamer");
|
||||
State = StreamState.Queued;
|
||||
bufferCancelSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
public string Stats() =>
|
||||
@@ -162,12 +163,9 @@ namespace NadekoBot.Classes.Music {
|
||||
int attempt = 0;
|
||||
while (true) {
|
||||
|
||||
//wait for the read pos to catch up with write pos
|
||||
while (buffer.writePos - buffer.readPos > 5.MB() && State != StreamState.Completed) {
|
||||
if (!bufferCancelSource.IsCancellationRequested) {
|
||||
Console.WriteLine("Canceling buffer token");
|
||||
Task.Run(() => bufferCancelSource.Cancel());
|
||||
}
|
||||
|
||||
prebufferingComplete = true;
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
@@ -228,11 +226,18 @@ namespace NadekoBot.Classes.Music {
|
||||
if (parent.OnBuffering != null)
|
||||
parent.OnBuffering();
|
||||
BufferSong();
|
||||
try {
|
||||
await Task.Delay(5000, bufferCancelSource.Token);
|
||||
} catch (Exception) {
|
||||
Console.WriteLine("Buffered enough in less than 5 seconds!");
|
||||
|
||||
// prebuffering wait stuff start
|
||||
int bufferAttempts = 0;
|
||||
int waitPerAttempt = 500;
|
||||
while (!prebufferingComplete && bufferAttempts++ < 10) {
|
||||
await Task.Delay(waitPerAttempt);
|
||||
}
|
||||
if (prebufferingComplete) {
|
||||
Console.WriteLine($"Prebuffering finished in {bufferAttempts*500}");
|
||||
}
|
||||
// prebuffering wait stuff end
|
||||
|
||||
//Task.Run(async () => { while (true) { Console.WriteLine($"Title: {parent.Title} State:{State}"); await Task.Delay(200); } });
|
||||
if (parent.OnStarted != null)
|
||||
parent.OnStarted();
|
||||
@@ -265,8 +270,6 @@ namespace NadekoBot.Classes.Music {
|
||||
} else
|
||||
attempt = 0;
|
||||
|
||||
|
||||
|
||||
if (State == StreamState.Completed) {
|
||||
Console.WriteLine("Canceled");
|
||||
break;
|
||||
|
@@ -12,10 +12,11 @@ using System.Timers;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Collections;
|
||||
|
||||
namespace NadekoBot
|
||||
{
|
||||
public class Trivia : DiscordCommand
|
||||
{
|
||||
//github.com/micmorris contributed quite a bit to making trivia better!
|
||||
namespace NadekoBot {
|
||||
public class Trivia : DiscordCommand {
|
||||
public static float HINT_TIME_SECONDS = 6;
|
||||
|
||||
public static Dictionary<ulong, TriviaGame> runningTrivias;
|
||||
|
||||
public Trivia() : base() {
|
||||
@@ -28,47 +29,37 @@ namespace NadekoBot
|
||||
|
||||
var tg = new TriviaGame(e, NadekoBot.client);
|
||||
runningTrivias.Add(e.Server.Id, tg);
|
||||
|
||||
|
||||
return tg;
|
||||
}
|
||||
|
||||
public TriviaQuestion GetCurrentQuestion(ulong serverId) => runningTrivias[serverId].currentQuestion;
|
||||
|
||||
public override Func<CommandEventArgs, Task> DoFunc() => async e =>
|
||||
{
|
||||
public override Func<CommandEventArgs, Task> DoFunc() => async e => {
|
||||
TriviaGame tg;
|
||||
if ((tg = StartNewGame(e)) != null)
|
||||
{
|
||||
await e.Send("**Trivia game started!**\nFirst player to get to 10 points wins! You have 30 seconds per question.\nUse command [tq] if game was started by accident.\nTyping [idfk] 15 seconds after the question has started will give you a hint.");
|
||||
}
|
||||
else
|
||||
if ((tg = StartNewGame(e)) != null) {
|
||||
await e.Send("**Trivia game started!**\nFirst player to get to 10 points wins! You have 30 seconds per question.\nUse command `tq` if game was started by accident.**");
|
||||
} else
|
||||
await e.Send("Trivia game is already running on this server. The question is:\n**" + GetCurrentQuestion(e.Server.Id).Question + "**");
|
||||
};
|
||||
|
||||
private Func<CommandEventArgs, Task> LbFunc() => async e =>
|
||||
{
|
||||
if (runningTrivias.ContainsKey(e.Server.Id))
|
||||
{
|
||||
private Func<CommandEventArgs, Task> LbFunc() => async e => {
|
||||
if (runningTrivias.ContainsKey(e.Server.Id)) {
|
||||
var lb = runningTrivias[e.User.Server.Id].GetLeaderboard();
|
||||
await e.Send(lb);
|
||||
}
|
||||
else
|
||||
} else
|
||||
await e.Send("Trivia game is not running on this server.");
|
||||
};
|
||||
|
||||
private Func<CommandEventArgs, Task> RepeatFunc() => async e =>
|
||||
{
|
||||
if (runningTrivias.ContainsKey(e.Server.Id))
|
||||
{
|
||||
private Func<CommandEventArgs, Task> RepeatFunc() => async e => {
|
||||
if (runningTrivias.ContainsKey(e.Server.Id)) {
|
||||
var lb = runningTrivias[e.User.Server.Id].GetLeaderboard();
|
||||
await e.Send(lb);
|
||||
}
|
||||
else
|
||||
} else
|
||||
await e.Send("Trivia game is not running on this server.");
|
||||
};
|
||||
|
||||
public override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
public override void Init(CommandGroupBuilder cgb) {
|
||||
cgb.CreateCommand("t")
|
||||
.Description("Starts a game of trivia.")
|
||||
.Alias("-t")
|
||||
@@ -87,18 +78,14 @@ namespace NadekoBot
|
||||
.Do(QuitFunc());
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> QuitFunc() => async e =>
|
||||
{
|
||||
if (runningTrivias.ContainsKey(e.Server.Id) && runningTrivias[e.Server.Id].ChannelId == e.Channel.Id)
|
||||
{
|
||||
await e.Send("Trivia will stop after this question. Run [**@NadekoBot clr**] to remove this bot's messages from the channel.");
|
||||
private Func<CommandEventArgs, Task> QuitFunc() => async e => {
|
||||
if (runningTrivias.ContainsKey(e.Server.Id) && runningTrivias[e.Server.Id].ChannelId == e.Channel.Id) {
|
||||
await e.Send("Trivia will stop after this question.");
|
||||
runningTrivias[e.Server.Id].StopGame();
|
||||
}
|
||||
else await e.Send("No trivias are running on this channel.");
|
||||
} else await e.Send("No trivias are running on this channel.");
|
||||
};
|
||||
|
||||
internal static void FinishGame(TriviaGame triviaGame)
|
||||
{
|
||||
internal static void FinishGame(TriviaGame triviaGame) {
|
||||
runningTrivias.Remove(runningTrivias.Where(kvp => kvp.Value == triviaGame).First().Key);
|
||||
}
|
||||
}
|
||||
@@ -127,11 +114,13 @@ namespace NadekoBot
|
||||
private Stopwatch stopwatch;
|
||||
private bool isQuit = false;
|
||||
|
||||
private System.Threading.CancellationTokenSource hintCancelSource;
|
||||
|
||||
public TriviaGame(CommandEventArgs starter, DiscordClient client) {
|
||||
this.users = new Dictionary<ulong, int>();
|
||||
this.client = client;
|
||||
this._serverId = starter.Server.Id;
|
||||
this._channellId= starter.Channel.Id;
|
||||
this._channellId = starter.Channel.Id;
|
||||
|
||||
oldQuestions = new List<string>();
|
||||
client.MessageReceived += PotentialGuess;
|
||||
@@ -149,12 +138,12 @@ namespace NadekoBot
|
||||
stopwatch = new Stopwatch();
|
||||
timeout.Elapsed += (s, e) => { TimeUp(); };
|
||||
|
||||
hintCancelSource = new System.Threading.CancellationTokenSource();
|
||||
TriviaQuestionsPool.Instance.Reload();
|
||||
LoadNextRound();
|
||||
}
|
||||
|
||||
private async void PotentialGuess(object sender, MessageEventArgs e)
|
||||
{
|
||||
private async void PotentialGuess(object sender, MessageEventArgs e) {
|
||||
if (e.Server == null || e.Channel == null) return;
|
||||
if (e.Server.Id != _serverId || !active)
|
||||
return;
|
||||
@@ -163,26 +152,24 @@ namespace NadekoBot
|
||||
return;
|
||||
|
||||
if (e.Message.Text.ToLower().Equals("idfk")) {
|
||||
GetHint(e);
|
||||
GetHint(e.Channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsAnswerCorrect(e.Message.Text.ToLower(), currentQuestion.Answer.ToLower()))
|
||||
{
|
||||
if (IsAnswerCorrect(e.Message.Text.ToLower(), currentQuestion.Answer.ToLower())) {
|
||||
active = false; //start pause between rounds
|
||||
timeout.Enabled = false;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (!users.ContainsKey(e.User.Id))
|
||||
users.Add(e.User.Id, 1);
|
||||
else
|
||||
{
|
||||
else {
|
||||
users[e.User.Id]++;
|
||||
}
|
||||
await e.Send( e.User.Mention + " Guessed it!\n The answer was: **" + currentQuestion.Answer + "**");
|
||||
await e.Send(e.User.Mention + " Guessed it!\n The answer was: **" + currentQuestion.Answer + "**");
|
||||
|
||||
if (users[e.User.Id] >= 10) {
|
||||
await e.Send( " We have a winner! It's " + e.User.Mention+"\n"+GetLeaderboard()+"\n To start a new game type '@NadekoBot t'");
|
||||
await e.Send(" We have a winner! It's " + e.User.Mention + "\n" + GetLeaderboard() + "\n To start a new game type '@NadekoBot t'");
|
||||
FinishGame();
|
||||
return;
|
||||
}
|
||||
@@ -192,16 +179,13 @@ namespace NadekoBot
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAnswerCorrect(string guess, string answer)
|
||||
{
|
||||
if(guess.Equals(answer))
|
||||
{
|
||||
private bool IsAnswerCorrect(string guess, string answer) {
|
||||
if (guess.Equals(answer)) {
|
||||
return true;
|
||||
}
|
||||
guess = CleanString(guess);
|
||||
answer = CleanString(answer);
|
||||
if (guess.Equals(answer))
|
||||
{
|
||||
if (guess.Equals(answer)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -209,12 +193,9 @@ namespace NadekoBot
|
||||
return Judge(guess.Length, answer.Length, levDistance);
|
||||
}
|
||||
|
||||
private bool Judge(int guessLength, int answerLength, int levDistance)
|
||||
{
|
||||
foreach(Tuple<int, int> level in strictness)
|
||||
{
|
||||
if(guessLength <= level.Item1 || answerLength <= level.Item1)
|
||||
{
|
||||
private bool Judge(int guessLength, int answerLength, int levDistance) {
|
||||
foreach (Tuple<int, int> level in strictness) {
|
||||
if (guessLength <= level.Item1 || answerLength <= level.Item1) {
|
||||
if (levDistance <= level.Item2)
|
||||
return true;
|
||||
else
|
||||
@@ -224,8 +205,7 @@ namespace NadekoBot
|
||||
return false;
|
||||
}
|
||||
|
||||
private string CleanString(string str)
|
||||
{
|
||||
private string CleanString(string str) {
|
||||
str = " " + str + " ";
|
||||
str = Regex.Replace(str, "\\s+", " ");
|
||||
str = Regex.Replace(str, "[^\\w\\d\\s]", "");
|
||||
@@ -239,30 +219,24 @@ namespace NadekoBot
|
||||
return str;
|
||||
}
|
||||
|
||||
public async void GetHint(MessageEventArgs e) {
|
||||
if (timeout != null && !isQuit && stopwatch.ElapsedMilliseconds > 10000)
|
||||
await e.Send( currentQuestion.Answer.Scramble());
|
||||
else {
|
||||
await e.Send( $"You have to wait {10-stopwatch.ElapsedMilliseconds/1000} more seconds in order to get a hint.");
|
||||
}
|
||||
public async void GetHint(Channel ch) {
|
||||
await ch.Send(currentQuestion.Answer.Scramble());
|
||||
}
|
||||
|
||||
public void StopGame() {
|
||||
isQuit = true;
|
||||
}
|
||||
|
||||
private void LoadNextRound()
|
||||
{
|
||||
private void LoadNextRound() {
|
||||
Channel ch = client.GetChannel(_channellId);
|
||||
|
||||
|
||||
if(currentQuestion!=null)
|
||||
|
||||
if (currentQuestion != null)
|
||||
oldQuestions.Add(currentQuestion.Question);
|
||||
|
||||
currentQuestion = TriviaQuestionsPool.Instance.GetRandomQuestion(oldQuestions);
|
||||
|
||||
if (currentQuestion == null || isQuit)
|
||||
{
|
||||
if (currentQuestion == null || isQuit) {
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
ch.Send("Trivia bot stopping. :\\\n" + GetLeaderboard());
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
@@ -279,12 +253,16 @@ namespace NadekoBot
|
||||
timeout.Enabled = true;//starting countdown of the next question
|
||||
stopwatch.Reset();
|
||||
stopwatch.Start();
|
||||
try {
|
||||
await Task.Delay((int)Trivia.HINT_TIME_SECONDS * 1000);
|
||||
GetHint(ch);
|
||||
} catch (Exception) { }
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
private async void TimeUp() {
|
||||
await client.GetChannel(_channellId)?.Send("**Time's up.**\nCorrect answer was: **" + currentQuestion.Answer+"**\n\n*[tq quits trivia][tl shows leaderboard]["+NadekoBot.botMention+" clr clears my messages]*");
|
||||
await client.GetChannel(_channellId)?.Send("**Time's up.**\nCorrect answer was: **" + currentQuestion.Answer + "**\n\n*[tq quits trivia][tl shows leaderboard][" + NadekoBot.botMention + " clr clears my messages]*");
|
||||
LoadNextRound();
|
||||
}
|
||||
|
||||
@@ -302,29 +280,26 @@ namespace NadekoBot
|
||||
public string GetLeaderboard() {
|
||||
if (users.Count == 0)
|
||||
return "";
|
||||
|
||||
|
||||
|
||||
string str = "**Leaderboard:**\n-----------\n";
|
||||
|
||||
if(users.Count>1)
|
||||
if (users.Count > 1)
|
||||
users.OrderBy(kvp => kvp.Value);
|
||||
|
||||
foreach (var KeyValuePair in users)
|
||||
{
|
||||
str += "**" + client.GetServer(_serverId).GetUser(KeyValuePair.Key).Name + "** has " +KeyValuePair.Value + (KeyValuePair.Value == 1 ? "point." : "points.") + Environment.NewLine;
|
||||
|
||||
foreach (var KeyValuePair in users) {
|
||||
str += "**" + client.GetServer(_serverId).GetUser(KeyValuePair.Key).Name + "** has " + KeyValuePair.Value + (KeyValuePair.Value == 1 ? "point." : "points.") + Environment.NewLine;
|
||||
}
|
||||
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
public class TriviaQuestion
|
||||
{
|
||||
public class TriviaQuestion {
|
||||
public string Category;
|
||||
public string Question;
|
||||
public string Answer;
|
||||
public TriviaQuestion(string q, string a)
|
||||
{
|
||||
public TriviaQuestion(string q, string a) {
|
||||
this.Question = q;
|
||||
this.Answer = a;
|
||||
}
|
||||
@@ -338,8 +313,7 @@ namespace NadekoBot
|
||||
public class TriviaQuestionsPool {
|
||||
private static TriviaQuestionsPool instance = null;
|
||||
|
||||
public static TriviaQuestionsPool Instance
|
||||
{
|
||||
public static TriviaQuestionsPool Instance {
|
||||
get {
|
||||
if (instance == null)
|
||||
instance = new TriviaQuestionsPool();
|
||||
@@ -352,21 +326,18 @@ namespace NadekoBot
|
||||
|
||||
private Random _r;
|
||||
|
||||
public TriviaQuestionsPool()
|
||||
{
|
||||
public TriviaQuestionsPool() {
|
||||
Reload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TriviaQuestion GetRandomQuestion(List<string> exclude) {
|
||||
if (pool.Count == 0)
|
||||
return null;
|
||||
|
||||
TriviaQuestion tq = pool[_r.Next(0, pool.Count)];
|
||||
if (exclude.Count > 0 && exclude.Count < pool.Count)
|
||||
{
|
||||
while (exclude.Contains(tq.Question))
|
||||
{
|
||||
if (exclude.Count > 0 && exclude.Count < pool.Count) {
|
||||
while (exclude.Contains(tq.Question)) {
|
||||
tq = pool[_r.Next(0, pool.Count)];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user