riff/bots/MysteriousCube.cs

123 lines
3.9 KiB
C#

using System.Data;
using System.Text.Json;
using riff;
public class MysteriousCube : IRCBot
{
private HttpClient RequestClient = new();
private const string AllTriviaQuestionsPath = "data/TriviaQuestions.json";
private const string UnaskedTriviaQuestionsPath = "data/UnaskedTriviaQuestions.json";
private TriviaQuestion[] AllTriviaQuestions;
private List<TriviaQuestion> UnaskedTriviaQuestions;
private bool ListeningForAnswer = false;
private TriviaQuestion? CurrentQuestion = null;
private Random Rand = new();
public MysteriousCube(string host, int port, string nick, string realname, List<string> permanentChannels)
: base(host, port, nick, realname, permanentChannels)
{
AllTriviaQuestions = LoadAllQuestions();
UnaskedTriviaQuestions = LoadUnaskedQuestions();
(string, Action<PRIVMSG>)[] commands = [
("echo", Echo),
("trivia", PostQuestion)
];
Action<PRIVMSG>[] listeners = [
AnswerListener
];
HookCommands(commands);
HookListeners(listeners);
}
private void Echo(PRIVMSG privmsg)
{
SendPrivmsg(privmsg.Sender, privmsg.Body);
}
private void PostQuestion(PRIVMSG privmsg)
{
var question = GetQuestion();
CurrentQuestion = question;
ListeningForAnswer = true;
SendPrivmsg(privmsg.Sender, $"Answer 'true' or 'false': {question.Question}");
}
private void AnswerListener(PRIVMSG privmsg)
{
if (!ListeningForAnswer || CurrentQuestion == null)
return;
string line = privmsg.Body.ToLower().Trim();
bool? answer = null;
if (line.StartsWith("true"))
answer = true;
else if (line.StartsWith("false"))
answer = false;
else
return;
ListeningForAnswer = false;
string response;
if (answer == CurrentQuestion.Answer)
response = $"{privmsg.Nick} is correct!";
else
response = $"{privmsg.Nick} is wrong!";
CurrentQuestion = null;
SendPrivmsg(privmsg.Sender, response);
}
private TriviaQuestion GetQuestion()
{
if (UnaskedTriviaQuestions.Count == 0)
UnaskedTriviaQuestions = AllTriviaQuestions.ToList();
TriviaQuestion question = UnaskedTriviaQuestions[Rand.Next(UnaskedTriviaQuestions.Count)];
UnaskedTriviaQuestions.Remove(question);
File.WriteAllText(UnaskedTriviaQuestionsPath, JsonSerializer.Serialize(UnaskedTriviaQuestions));
return question;
}
private TriviaQuestion[] LoadAllQuestions()
{
try
{
using (FileStream stream = File.OpenRead(AllTriviaQuestionsPath))
{
TriviaQuestion[] questions = JsonSerializer.Deserialize<TriviaQuestion[]>(stream)!;
if (questions == null)
throw new NoNullAllowedException();
return questions;
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Trivia questions not downloaded. Use download_trivia.py script.");
Environment.Exit(1);
return Array.Empty<TriviaQuestion>(); // Unreachable, but required for compiler
}
}
private List<TriviaQuestion> LoadUnaskedQuestions()
{
try
{
using (FileStream stream = File.OpenRead(UnaskedTriviaQuestionsPath))
{
List<TriviaQuestion> questions = JsonSerializer.Deserialize<List<TriviaQuestion>>(stream)!;
if (questions == null)
throw new NoNullAllowedException();
return questions;
}
}
catch (FileNotFoundException)
{
return AllTriviaQuestions.ToList();
}
}
}
public class TriviaQuestion
{
public required string Question { get; set; }
public required bool Answer { get; set; }
}