Skip to content

Commit

Permalink
Switching to Unity-Friendly Timers
Browse files Browse the repository at this point in the history
- Removes System.Timers from Admin-Mod
- Removes System.Timers from Announcements
  • Loading branch information
data-bomb committed Mar 20, 2024
1 parent 9643de5 commit c14b84c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 69 deletions.
101 changes: 62 additions & 39 deletions Si_AdminMod/ChatVotes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ You should have received a copy of the GNU General Public License
using Il2Cpp;
#endif

using HarmonyLib;
using MelonLoader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using UnityEngine;

namespace SilicaAdminMod
{
Expand All @@ -41,7 +42,7 @@ public static class ChatVotes

public delegate void VoteHandler(ChatVoteResults results);

private static Timer? Timer_VoteDuration;
private static float Timer_TallyVote;

static HelperMethods.CommandCallback voteChatCallback = Command_VoteChat;

Expand Down Expand Up @@ -123,52 +124,74 @@ public static void HoldVote(ChatVoteBallot ballot)

private static void StartVoteDurationTimer()
{
double interval = SiAdminMod.Pre_Admin_VoteDuration.Value * 1000.0f;
MelonLogger.Msg("Starting vote timer with duration " + interval.ToString());
Timer_VoteDuration = new Timer(interval);
MelonLogger.Msg("Starting vote timer with duration " + SiAdminMod.Pre_Admin_VoteDuration.Value.ToString());
voteInProgress = true;
Timer_VoteDuration.Elapsed += new ElapsedEventHandler(HandleVoteTimerExpired);
Timer_VoteDuration.AutoReset = false;
Timer_VoteDuration.Enabled = true;
HelperMethods.StartTimer(ref Timer_TallyVote);
}

// don't access anything from melonloader inside the timer callback
private static void HandleVoteTimerExpired(object? source, ElapsedEventArgs e)
#if NET6_0
[HarmonyPatch(typeof(MusicJukeboxHandler), nameof(MusicJukeboxHandler.Update))]
#else
[HarmonyPatch(typeof(MusicJukeboxHandler), "Update")]
#endif
private static class ApplyPatch_MusicJukeboxHandlerUpdate
{

if (currentVoteResults == null)
{
MelonLogger.Warning("Current vote results unavailable for timer expiration.");
voteInProgress = false;
return;
}

OptionVoteResult winningResult = new OptionVoteResult
{
Votes = -1,
Command = "invalid"
};

foreach (OptionVoteResult currentVoteResult in currentVoteResults.DetailedResults)
private static void Postfix(MusicJukeboxHandler __instance)
{
// determine winner
if (currentVoteResult.Votes > winningResult.Votes)
try
{
winningResult = currentVoteResult;
}

MelonLogger.Msg("Found command " + currentVoteResult.Command + " with votes " + currentVoteResult.Votes);
// check if timer expired while the game is in-progress
if (HelperMethods.IsTimerActive(Timer_TallyVote))
{
Timer_TallyVote += Time.deltaTime;

if (Timer_TallyVote >= SiAdminMod.Pre_Admin_VoteDuration.Value)
{
Timer_TallyVote = HelperMethods.Timer_Inactive;

if (currentVoteResults == null)
{
MelonLogger.Warning("Current vote results unavailable for timer expiration.");
voteInProgress = false;
return;
}

OptionVoteResult winningResult = new OptionVoteResult
{
Votes = -1,
Command = "invalid"
};

foreach (OptionVoteResult currentVoteResult in currentVoteResults.DetailedResults)
{
// determine winner
if (currentVoteResult.Votes > winningResult.Votes)
{
winningResult = currentVoteResult;
}

MelonLogger.Msg("Found command " + currentVoteResult.Command + " with votes " + currentVoteResult.Votes);

// unregister commands for current vote
PlayerMethods.UnregisterPlayerPhrase(currentVoteResult.Command);
}

// assign winner
currentVoteResults.WinningCommand = winningResult.Command;

// call the vote handler
voteInProgress = false;
currentVoteResults.VoteHandler(currentVoteResults);
}

// unregister commands for current vote
PlayerMethods.UnregisterPlayerPhrase(currentVoteResult.Command);
}
}
catch (Exception exception)
{
HelperMethods.PrintError(exception, "Failed in MusicJukeboxHandler::Update");
}
}

// assign winner
currentVoteResults.WinningCommand = winningResult.Command;

// call the vote handler
voteInProgress = false;
currentVoteResults.VoteHandler(currentVoteResults);
}
}
}
63 changes: 33 additions & 30 deletions Si_Announcements/Si_Announcements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ You should have received a copy of the GNU General Public License
using MelonLoader;
using MelonLoader.Utils;
using Si_Announcements;
using System.Timers;
using System;
using System.IO;
using System.Collections.Generic;
using SilicaAdminMod;
using System.Linq;
using UnityEngine;

[assembly: MelonInfo(typeof(Announcements), "Server Announcements", "1.1.7", "databomb", "https://github.com/data-bomb/Silica")]
[assembly: MelonInfo(typeof(Announcements), "Server Announcements", "1.1.8", "databomb", "https://github.com/data-bomb/Silica")]
[assembly: MelonGame("Bohemia Interactive", "Silica")]
[assembly: MelonOptionalDependencies("Admin Mod")]

Expand All @@ -48,11 +48,12 @@ public class Announcements : MelonMod
static MelonPreferences_Entry<int> _Announcements_SecondsBetweenMessages = null!;
static MelonPreferences_Entry<bool> _Announcements_ShowIfLastChatWasAnnouncement = null!;

static Timer announcementTimer = null!;
static readonly float Timer_Inactive = -123.0f;

static float Timer_Announcement = Timer_Inactive;
static int announcementCount;
static string[]? announcementsText;
static string? lastChatMessage;
static bool timerExpired;

public override void OnInitializeMelon()
{
Expand Down Expand Up @@ -89,13 +90,6 @@ public override void OnInitializeMelon()
}

MelonLogger.Msg("Loaded announcements.txt file with " + announcementsText.Length + " announcements.");

double interval = _Announcements_SecondsBetweenMessages.Value * 1000.0f;
announcementTimer = new System.Timers.Timer(interval);
announcementTimer.Elapsed += new ElapsedEventHandler(TimerCallbackAnnouncement);
announcementTimer.AutoReset = true;
announcementTimer.Enabled = true;

}
catch (Exception exception)
{
Expand All @@ -106,6 +100,8 @@ public override void OnInitializeMelon()
#if NET6_0
public override void OnLateInitializeMelon()
{
HelperMethods.StartTimer(ref Timer_Announcement);

bool QListLoaded = RegisteredMelons.Any(m => m.Info.Name == "QList");
if (!QListLoaded)
{
Expand All @@ -122,11 +118,6 @@ public override void OnLateInitializeMelon()
}
#endif

private static void TimerCallbackAnnouncement(object? source, ElapsedEventArgs e)
{
timerExpired = true;
}

#if NET6_0
[HarmonyPatch(typeof(MusicJukeboxHandler), nameof(MusicJukeboxHandler.Update))]
#else
Expand All @@ -138,30 +129,42 @@ private static void Postfix(MusicJukeboxHandler __instance)
{
try
{

// check if timer expired while the game is in-progress
if (GameMode.CurrentGameMode.GameOngoing == true && timerExpired == true)
if (HelperMethods.IsTimerActive(Timer_Announcement))
{
timerExpired = false;
Timer_Announcement += Time.deltaTime;

if (announcementsText == null)
if (Timer_Announcement >= _Announcements_SecondsBetweenMessages.Value)
{
return;
}
Timer_Announcement = Timer_Inactive;

if (!_Announcements_ShowIfLastChatWasAnnouncement.Value)
{
// check if the last chat message was an announcement
if (IsPreviousChatMessageAnnouncement(lastChatMessage))
if (announcementsText == null)
{
MelonLogger.Msg("Skipping Announcement - Repeated Message");
return;
}
}

string nextAnnouncement = GetNextAnnouncement();
// skip if game is not ongoign
if (!GameMode.CurrentGameMode.GameOngoing)
{
return;
}

Player broadcastPlayer = HelperMethods.FindBroadcastPlayer();
broadcastPlayer.SendChatMessage(nextAnnouncement);
if (!_Announcements_ShowIfLastChatWasAnnouncement.Value)
{
// check if the last chat message was an announcement
if (IsPreviousChatMessageAnnouncement(lastChatMessage))
{
MelonLogger.Msg("Skipping Announcement - Repeated Message");
return;
}
}

string nextAnnouncement = GetNextAnnouncement();

Player broadcastPlayer = HelperMethods.FindBroadcastPlayer();
broadcastPlayer.SendChatMessage(nextAnnouncement);
}
}
}
catch (Exception exception)
Expand Down

0 comments on commit c14b84c

Please sign in to comment.