Skip to content

Commit

Permalink
Version 1.38 (#83)
Browse files Browse the repository at this point in the history
* Updated version to 1.38 and added support for auto-reset weeklies.

* Changed reset time to UTC 18 0 0

* Removed xvfb hack

* Removed xvfb hack (for realz).

* Cleanup
  • Loading branch information
sbzappa authored Aug 16, 2024
1 parent 1272a0c commit ad489a7
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 81 deletions.
85 changes: 11 additions & 74 deletions MaraBot/Core/CommandUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,16 @@ public int Compare(KeyValuePair<string, MysterySetting> x, KeyValuePair<string,
}
}


private static async Task<(Preset Preset, string Seed, string ValidationHash)> GenerateMysteryRaceAsync(
CommandContext ctx,
/// <summary>
/// Generate a race a randomized weekly settings
/// </summary>
/// <param name="author">Author of the race. "Mara" if null or empty.</param>
/// <param name="name">Name of the race.</param>
/// <param name="description">Description of the race</param>
/// <param name="mysterySettings">List of weekly settings</param>
/// <param name="options">Randomizer options</param>
/// <returns>Tuple of preset and seed string.</returns>
public static async Task<(Preset Preset, string Seed, string ValidationHash)> GenerateMysteryRaceAsync(
string author,
string name,
string description,
Expand Down Expand Up @@ -742,7 +749,7 @@ await Task.Run(() =>
case AttachmentFileType.LogFile:
return await LoadLogAttachmentAsync(ctx, author, name, description, options);
case AttachmentFileType.None:
return await GenerateMysteryRaceAsync(ctx, author, name, description, mysterySettings, options);
return await GenerateMysteryRaceAsync(author, name, description, mysterySettings, options);

default:
throw new InvalidOperationException(errorMessage);
Expand Down Expand Up @@ -778,68 +785,6 @@ await Task.Run(() =>
if (Environment.OSVersion.Platform == PlatformID.Unix ||
Environment.OSVersion.Platform == PlatformID.MacOSX)
{
Process xvfbProcess = null;
var framebufferFile = "/tmp/Xvfb_screen0";

var displayEnv = Environment.GetEnvironmentVariable("DISPLAY");
if (String.IsNullOrEmpty(displayEnv))
{
var displayNumber = 1;

xvfbProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "Xvfb",
ArgumentList =
{
$":{displayNumber}",
"-fbdir",
"/tmp/"
}
}
};

try
{
xvfbProcess.Start();
}
catch(Exception exception)
{
xvfbProcess.Dispose();
throw new InvalidOperationException(
"This feature requires Xvfb to setup a virtual display.\n" +
$"Exception: {exception.Message}"
);
}

var timeout = TimeSpan.FromMilliseconds(5000);
DateTimeOffset timeoutAt = DateTimeOffset.UtcNow + timeout;
var fileExists = false;
while (true)
{
if (File.Exists(framebufferFile))
{
fileExists = true;
break;
}
if (DateTimeOffset.UtcNow >= timeoutAt) break;
await Task.Delay(10);
}

if (fileExists)
displayEnv = $":{displayNumber}";
else
{
xvfbProcess?.Kill();
xvfbProcess?.Dispose();

throw new InvalidOperationException(
$"Could not find Xvfb framebuffer file {framebufferFile}."
);
}
}

var tcs = new TaskCompletionSource<int>();
var randomizerProcess = new Process
{
Expand All @@ -859,8 +804,6 @@ await Task.Run(() =>
EnableRaisingEvents = true
};

randomizerProcess.StartInfo.EnvironmentVariables["DISPLAY"] = displayEnv;

randomizerProcess.Exited += (sender, args) =>
{
tcs.SetResult(randomizerProcess.ExitCode);
Expand All @@ -873,19 +816,13 @@ await Task.Run(() =>
}
catch (Exception exception)
{
xvfbProcess?.Dispose();
throw new InvalidOperationException(
"This feature requires mono to run the randomizer executable.\n" +
$"Exception: {exception.Message}"
);
}

await tcs.Task;

File.Delete(framebufferFile);

xvfbProcess?.Kill();
xvfbProcess?.Dispose();
}
else
{
Expand Down
8 changes: 4 additions & 4 deletions MaraBot/Core/WeeklyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ namespace MaraBot.Core
public static class WeeklyUtils
{
static Random s_TimeBasedRandom = new Random(DateTime.Now.GetHashCode());
static DateTime s_FirstWeek = new DateTime(2021, 08, 13, 0, 0, 0);
static DateTime s_FirstWeek = new DateTime(2021, 08, 13, 18, 0, 0, DateTimeKind.Utc);
static readonly TimeSpan s_WeeklyDuration = TimeSpan.FromDays(7.0);
//static readonly TimeSpan s_WeeklyDuration = TimeSpan.FromMinutes(1.0);

enum ChallengeDuration
{
Expand All @@ -22,7 +23,6 @@ enum ChallengeDuration

static readonly ChallengeDuration s_ChallengeDuration = ChallengeDuration.EveryMonth;


/// <summary>
/// Retrieves the duration until next weekly reset.
/// </summary>
Expand Down Expand Up @@ -120,9 +120,9 @@ public static string GetRandomSeed()
public static int GetWeekNumber()
{
var elapsed = DateTime.UtcNow.Subtract(s_FirstWeek);
var elapsedWeeks = elapsed.Days / 7;
var divide = elapsed.Divide(s_WeeklyDuration);

return elapsedWeeks;
return (int)Math.Truncate(divide);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion MaraBot/Messages/Display.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public static async Task<DiscordEmbedBuilder> LeaderboardEmbedAsync(DiscordGuild
IEnumerable<KeyValuePair<string, TimeSpan>> leaderboard = weekly.Leaderboard;

// To avoid giving away any ranking, avoid sorting the leaderboard when preventing spoilers.
if (!preventSpoilers)
if (leaderboard != null && !preventSpoilers)
{
leaderboard = leaderboard
.OrderBy(kvp => kvp.Value);
Expand Down
14 changes: 14 additions & 0 deletions MaraBot/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,26 @@ static async Task MainAsync()
};
var resetChallengeTask = resetChallenge.StartAsync();

var resetWeekly = new ResetWeekly
{
Discord = discord,
Weekly = weekly,
Options = options,
Config = config,
MutexRegistry = mutexRegistry,
MysterySettings = mysterySettings
};
var resetWeeklyTask = resetWeekly.StartAsync();

await discord.StartAsync();

await Task.Delay(-1);

resetChallenge.StopAsync();
await resetChallengeTask;

resetWeekly.StopAsync();
await resetWeeklyTask;
}
}
}
5 changes: 5 additions & 0 deletions MaraBot/Tasks/ResetChallenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public async Task StartAsync()
}

var duration = WeeklyUtils.GetRemainingChallengeDuration(timeStamp);

// At most check remaining duration every day.
if (duration > TimeSpan.FromDays(1))
duration = TimeSpan.FromDays(1);

if (duration > TimeSpan.Zero)
await Task.Delay(duration, _cts.Token);
}
Expand Down
65 changes: 64 additions & 1 deletion MaraBot/Tasks/ResetWeekly.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DSharpPlus;
using MaraBot.Core;
using MaraBot.IO;
using MaraBot.Messages;
using Microsoft.Extensions.Logging;

namespace MaraBot.Tasks
{
Expand All @@ -14,8 +16,27 @@ public class ResetWeekly
private readonly CancellationTokenSource _cts = new CancellationTokenSource();

public DiscordShardedClient Discord { get; set; }

/// <summary>
/// Weekly settings.
/// </summary>
public Weekly Weekly { get; set; }
public Config Config { get; set; }
/// <summary>
/// Randomizer Options.
/// </summary>
public IReadOnlyDictionary<string, Option> Options { private get; set; }
/// <summary>
/// Mystery Settings.
/// </summary>
public IReadOnlyDictionary<string, MysterySetting> MysterySettings { private get; set; }
/// <summary>
/// Bot configuration.
/// </summary>
public Config Config { private get; set; }
/// <summary>
/// Mutex registry.
/// </summary>
public MutexRegistry MutexRegistry { private get; set; }

public async Task StartAsync()
{
Expand Down Expand Up @@ -73,6 +94,48 @@ await CommandUtils.SendToChannelAsync(
// Set weekly to blank with a fresh leaderboard.
Weekly.Load(Weekly.NotSet);
await WeeklyIO.StoreWeeklyAsync(Weekly);

// Generate a new race.
var name = $"Weekly {currentWeek}";

Weekly.Preset = default;
Weekly.PresetName = String.Empty;

try
{
(Weekly.Preset, Weekly.Seed, _) = await CommandUtils.GenerateMysteryRaceAsync(default, name, default, MysterySettings, Options);
}
catch (InvalidOperationException e)
{
Discord.Logger.LogWarning(
"Could not generate weekly race.\n" +
e.Message);
return;
}

try
{
var (newPreset, newSeed, newValidationHash) = await CommandUtils.GenerateValidationHash(Weekly.Preset, Weekly.Seed, Config, Options, MutexRegistry);
if (newPreset.Equals(Weekly.Preset) && newSeed.Equals(Weekly.Seed))
{
Weekly.ValidationHash = newValidationHash;
}
}
catch (Exception exception)
{
Discord.Logger.LogWarning(
"Could not create a validation hash.\n" +
exception.Message);
}

await WeeklyIO.StoreWeeklyAsync(Weekly);

var raceEmbed = Display.RaceEmbed(Weekly.Preset, Weekly.Seed, Weekly.ValidationHash);

foreach (var guild in guilds)
{
await CommandUtils.SendToChannelAsync(guild, Config.WeeklyChannel, raceEmbed);
}
}

public void StopAsync()
Expand Down
2 changes: 1 addition & 1 deletion config/mystery.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": {
"values": {
"1.36": 100
"1.38": 100
}
},

Expand Down

0 comments on commit ad489a7

Please sign in to comment.