diff --git a/MultiUserRaffleBot/Models/ConfigData.cs b/MultiUserRaffleBot/Models/ConfigData.cs index 458829c..bb3f768 100644 --- a/MultiUserRaffleBot/Models/ConfigData.cs +++ b/MultiUserRaffleBot/Models/ConfigData.cs @@ -87,6 +87,9 @@ public class ConfigData [JsonProperty] public int MaxMessageLifetime = 5; + [JsonProperty] + public bool EnableLogging = false; + /*** Config Loading/Saving ***/ public static ConfigData? LoadConfigData() { diff --git a/MultiUserRaffleBot/Models/ConsoleService.cs b/MultiUserRaffleBot/Models/ConsoleService.cs index 1d543b0..8e2cb9e 100644 --- a/MultiUserRaffleBot/Models/ConsoleService.cs +++ b/MultiUserRaffleBot/Models/ConsoleService.cs @@ -7,6 +7,7 @@ using MultiUserRaffleBot.Types; using Avalonia.Controls; using System.Linq; +using System.IO; namespace MultiUserRaffleBot.Models { @@ -34,17 +35,22 @@ public class ConsoleService : BaseServiceTickable public ObservableCollection ConsoleMessages { get; private set; } public static DataGrid? ConsoleHistory; private int MaxMessageLifetime = 5; + private static string LogFileName = "log.txt"; + private bool LoggingEnabled = false; public ConsoleService() { ConsoleMessages = []; + if (File.Exists(LogFileName)) + File.Delete(LogFileName); } public override ConsoleSources GetSource() => ConsoleSources.None; - public void SetMaxMessageLifetime(int value) + public void ApplySettings(int messageLifetime, bool enableLogs) { - MaxMessageLifetime = value; + MaxMessageLifetime = messageLifetime; + LoggingEnabled = enableLogs; } public void AddMessage(string inMessage, ConsoleSources source = ConsoleSources.None) @@ -53,6 +59,8 @@ public void AddMessage(string inMessage, ConsoleSources source = ConsoleSources. if (string.IsNullOrWhiteSpace(inMessage)) return; + PrintToLog(inMessage, source); + Dispatcher.UIThread.Post(() => { ConsoleMessages.Add(new ConsoleMessage(inMessage, source)); ConsoleHistory?.ScrollIntoView(ConsoleMessages.Last(), null); @@ -69,6 +77,18 @@ public void ClearAllMessages() Dispatcher.UIThread.Post(() => ConsoleMessages.Clear()); } + private void PrintToLog(string inMessage, ConsoleSources source) + { + if (!LoggingEnabled) + return; + + // Print out the winner to a log file. + using (StreamWriter FileWriter = File.AppendText(LogFileName)) + { + FileWriter.WriteLine($"[{DateTime.Now}]({source}) {inMessage}"); + } + } + protected override async Task Tick() { using PeriodicTimer timer = new(TimeSpan.FromSeconds(30)); diff --git a/MultiUserRaffleBot/Models/TwitchService.cs b/MultiUserRaffleBot/Models/TwitchService.cs index f8a53f0..3c38979 100644 --- a/MultiUserRaffleBot/Models/TwitchService.cs +++ b/MultiUserRaffleBot/Models/TwitchService.cs @@ -26,16 +26,18 @@ public class TwitchService : BaseService { private readonly TwitchClient client; private readonly TwitchSettings settings; - private Random rng = new(); + private Random rng = new Random(Guid.NewGuid().GetHashCode()); private CancellationTokenSource cancelToken = new(); // Raffle Data - private const string WinnerLogFile = "raffle.txt"; private bool RaffleOpen = false; + private const string WinnerLogFile = "raffle.txt"; + private Collection Entries = new(); + + // Raffle Strings private string CurrentRaffleMessage = string.Empty; private string CurrentRafflePrize = string.Empty; private string CurrentWinnerName = string.Empty; - private Collection Entries = new(); public override ConsoleSources GetSource() => ConsoleSources.Twitch; @@ -135,28 +137,6 @@ public void JoinChannels(TwitchSettings NewSettings) } /*** Raffle Support ***/ - private void SetCurrentRaffleMessage(RaffleState state, int raffleLength = 600) - { - switch (state) - { - case RaffleState.RaffleOpen: - CurrentRaffleMessage = $"Drawing is now open for {CurrentRafflePrize} for {raffleLength / 60} minutes! Type !enter to enter."; - break; - case RaffleState.WinnerPicked: - CurrentRaffleMessage = $"Winner of {CurrentRafflePrize} is @{CurrentWinnerName}! Type !confirm within 5 minutes to confirm!"; - break; - case RaffleState.Claimed: - CurrentRaffleMessage = $"{CurrentRafflePrize} claimed by @{CurrentWinnerName}! Congrats! {settings.WinnerInstructions}"; - break; - case RaffleState.NoEntries: - CurrentRaffleMessage = $"Drawing for prize {CurrentRafflePrize} ended with no claims. Prize may appear again in the future..."; - break; - default: - CurrentRaffleMessage = ""; - break; - } - } - public void StartRaffle(string rafflePrize, int raffleLength) { // If the raffle prize string is just empty, skip the command @@ -164,7 +144,6 @@ public void StartRaffle(string rafflePrize, int raffleLength) return; RaffleOpen = true; - Entries.Clear(); CurrentRafflePrize = rafflePrize; SetCurrentRaffleMessage(RaffleState.RaffleOpen, raffleLength); @@ -201,7 +180,7 @@ public void PickRaffle() } // Choose a winner - int ChooseIndex = rng.Next(Entries.Count); + int ChooseIndex = rng.Next(0, Entries.Count); CurrentWinnerName = Entries[ChooseIndex].ToLower(); // Print a message @@ -230,7 +209,29 @@ private void WriteRaffleResult(string winner) { FileWriter.WriteLine($"{CurrentRafflePrize} winner is {winner}"); } - CurrentRafflePrize = string.Empty; + ResetRaffle(); + } + + private void SetCurrentRaffleMessage(RaffleState state, int raffleLength = 600) + { + switch (state) + { + case RaffleState.RaffleOpen: + CurrentRaffleMessage = $"Drawing is now open for {CurrentRafflePrize} for {raffleLength / 60} minutes! Type !enter to enter."; + break; + case RaffleState.WinnerPicked: + CurrentRaffleMessage = $"Winner of {CurrentRafflePrize} is @{CurrentWinnerName}! Type !confirm within 5 minutes to confirm!"; + break; + case RaffleState.Claimed: + CurrentRaffleMessage = $"{CurrentRafflePrize} claimed by @{CurrentWinnerName}! Congrats! {settings.WinnerInstructions}"; + break; + case RaffleState.NoEntries: + CurrentRaffleMessage = $"Drawing for prize {CurrentRafflePrize} ended with no claims. Prize may appear again in the future..."; + break; + default: + CurrentRaffleMessage = string.Empty; + break; + } } private void CancelWait() @@ -240,6 +241,13 @@ private void CancelWait() cancelToken = new(); } + private void ResetRaffle() + { + CurrentRafflePrize = string.Empty; + CurrentWinnerName = string.Empty; + Entries.Clear(); + } + /*** Handle Twitch Events ***/ private void OnChannelJoined(object unused, OnJoinedChannelArgs args) { @@ -264,6 +272,7 @@ private void OnCommandReceived(object unused, OnChatCommandReceivedArgs args) if (RaffleOpen && !Entries.Contains(user)) { Entries.Add(user); + PrintMessage($"{user} entered at index {Entries.Count}"); if (settings.RespondToRaffleEntry) SendMessageToChannel(args.Command.ChatMessage.Channel, $"@{user} you have entered!"); } @@ -275,6 +284,7 @@ private void OnCommandReceived(object unused, OnChatCommandReceivedArgs args) CancelWait(); // Push updates to everyone + PrintMessage($"{CurrentWinnerName} has claimed the prize {CurrentRafflePrize}"); SetCurrentRaffleMessage(RaffleState.Claimed); WriteRaffleResult(CurrentWinnerName); SendCurrentStatusToAllChannels(); diff --git a/MultiUserRaffleBot/ViewModels/MainViewModel.cs b/MultiUserRaffleBot/ViewModels/MainViewModel.cs index ba9f06a..28f0e01 100644 --- a/MultiUserRaffleBot/ViewModels/MainViewModel.cs +++ b/MultiUserRaffleBot/ViewModels/MainViewModel.cs @@ -102,7 +102,7 @@ private void LoadConfigs() } // Set the max message lifetime - Console.SetMaxMessageLifetime(Config.MaxMessageLifetime); + Console.ApplySettings(Config.MaxMessageLifetime, Config.EnableLogging); Raffle.BuildRaffleData(Config.RaffleData); }