154 lines
4.9 KiB
C#
154 lines
4.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Text.Json;
|
|
using riff;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
|
|
public class MysteriousCube : IRCBot
|
|
{
|
|
// private HttpClient RequestClient = new();
|
|
private TriviaQuestion[] AllTriviaQuestions;
|
|
private const string AllTriviaQuestionsPath = "data/TriviaQuestions.json";
|
|
private Dictionary<string, TriviaQuestion?> CurrentQuestions = [];
|
|
private readonly Random Rand = new();
|
|
|
|
public MysteriousCube(string host, int port, string nick, string realname, List<string> permanentChannels)
|
|
: base(host, port, nick, realname, permanentChannels)
|
|
{
|
|
AllTriviaQuestions = LoadAllQuestions();
|
|
|
|
(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();
|
|
CurrentQuestions[privmsg.Sender] = question;
|
|
SendPrivmsg(privmsg.Sender, $"Answer 'true' or 'false': {question.Question}");
|
|
}
|
|
|
|
private void AnswerListener(PRIVMSG privmsg)
|
|
{
|
|
TriviaQuestion? currentQuestion = CurrentQuestions.GetValueOrDefault(privmsg.Sender);
|
|
if (currentQuestion == null)
|
|
return;
|
|
string line = privmsg.Body.ToLower().Trim();
|
|
bool? answer;
|
|
if (line.StartsWith("true"))
|
|
answer = true;
|
|
else if (line.StartsWith("false"))
|
|
answer = false;
|
|
else
|
|
return;
|
|
string response;
|
|
using (var db = new MysteriousCubeDatabaseContext())
|
|
{
|
|
bool correct = answer == currentQuestion.Answer;
|
|
var user = db.Users.Find(privmsg.Nick);
|
|
if (user == null)
|
|
{
|
|
user = new User { Nick = privmsg.Nick, TriviaScore = 0 };
|
|
db.Users.Add(user);
|
|
db.SaveChanges();
|
|
user = db.Users.Find(privmsg.Nick)!;
|
|
}
|
|
if (correct)
|
|
user.TriviaScore += 1;
|
|
else
|
|
user.TriviaScore =- 1;
|
|
db.Users.Update(user);
|
|
db.SaveChanges();
|
|
string phrasing = correct ? "correct" : "wrong";
|
|
response = $"{privmsg.Nick} is {phrasing}! {privmsg.Nick} has a score of {user.TriviaScore}.";
|
|
CurrentQuestions[privmsg.Sender] = null;
|
|
}
|
|
SendPrivmsg(privmsg.Sender, response);
|
|
}
|
|
|
|
private TriviaQuestion GetQuestion()
|
|
{
|
|
using (var db = new MysteriousCubeDatabaseContext())
|
|
{
|
|
var questions = db.UnaskedTriviaQuestions.ToList();
|
|
Console.WriteLine($"{questions.Count}");
|
|
if (db.UnaskedTriviaQuestions.Count() == 0)
|
|
{
|
|
foreach (var q in AllTriviaQuestions)
|
|
db.UnaskedTriviaQuestions.Add(q);
|
|
questions = db.UnaskedTriviaQuestions.ToList();
|
|
}
|
|
TriviaQuestion question = questions[Rand.Next(questions.Count)];
|
|
db.UnaskedTriviaQuestions.Remove(question);
|
|
db.SaveChanges();
|
|
return question;
|
|
}
|
|
}
|
|
|
|
private TriviaQuestion[] LoadAllQuestions()
|
|
{
|
|
try
|
|
{
|
|
using (FileStream stream = File.OpenRead(AllTriviaQuestionsPath))
|
|
{
|
|
var 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
|
|
}
|
|
}
|
|
|
|
public class MysteriousCubeDatabaseContext : DbContext
|
|
{
|
|
public DbSet<TriviaQuestion> UnaskedTriviaQuestions { get; set; }
|
|
public DbSet<User> Users { get; set; }
|
|
public string DbPath = "data/mysterious_cube.sqlite";
|
|
|
|
// public UnaskedTriviaQuestionsContext()
|
|
// {
|
|
// //
|
|
// }
|
|
|
|
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
|
=> options.UseSqlite($"Data Source=data/mysterious_cube.sqlite");
|
|
}
|
|
|
|
[Table("UnaskedTriviaQuestions")]
|
|
public class TriviaQuestion
|
|
{
|
|
[Key]
|
|
public required string Question { get; set; }
|
|
public required bool Answer { get; set; }
|
|
}
|
|
|
|
[Table("Users")]
|
|
public class User
|
|
{
|
|
[Key]
|
|
public required string Nick { get; set; }
|
|
public required int TriviaScore { get; set; }
|
|
}
|
|
} |