Skip to content

Commit

Permalink
Merge pull request #20 from BigBang1112/dev
Browse files Browse the repository at this point in the history
RandomizerTMF 1.1.5
  • Loading branch information
BigBang1112 authored Aug 11, 2024
2 parents bf3c179 + e231580 commit 881fea3
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace RandomizerTMF.Logic.Exceptions;

[Serializable]
public class ConfigCorruptedException : Exception
{
public ConfigCorruptedException() { }
public ConfigCorruptedException(string message) : base(message) { }
public ConfigCorruptedException(string message, Exception inner) : base(message, inner) { }
}
19 changes: 17 additions & 2 deletions Src/RandomizerTMF.Logic/RandomizerRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ public class RandomizerRules
};

public Dictionary<ESite, HashSet<uint>> BannedMaps { get; init; } = [];
public bool AvoidSkippedMaps { get; set; }

public void Serialize(BinaryWriter writer, int version)
{
writer.Write(TimeLimit.Ticks);
writer.Write(NoUnlimiter);
RequestRules.Serialize(writer);
RequestRules.Serialize(writer, version);

if (version < 1)
{
Expand All @@ -37,13 +38,20 @@ public void Serialize(BinaryWriter writer, int version)
writer.Write(id);
}
}

if (version < 2)
{
return;
}

writer.Write(AvoidSkippedMaps);
}

public void Deserialize(BinaryReader r, int version)
{
TimeLimit = TimeSpan.FromTicks(r.ReadInt64());
NoUnlimiter = r.ReadBoolean();
RequestRules.Deserialize(r);
RequestRules.Deserialize(r, version);

if (version < 1)
{
Expand All @@ -63,5 +71,12 @@ public void Deserialize(BinaryReader r, int version)
}
BannedMaps.Add(site, ids);
}

if (version < 2)
{
return;
}

AvoidSkippedMaps = r.ReadBoolean();
}
}
8 changes: 4 additions & 4 deletions Src/RandomizerTMF.Logic/RandomizerTMF.Logic.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>1.1.4</Version>
<Version>1.1.5</Version>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -13,10 +13,10 @@

<ItemGroup>
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageReference Include="GBX.NET" Version="2.0.5" />
<PackageReference Include="GBX.NET.LZO" Version="2.0.0" />
<PackageReference Include="GBX.NET" Version="2.0.6" />
<PackageReference Include="GBX.NET.LZO" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="System.IO.Abstractions" Version="21.0.22" />
<PackageReference Include="System.IO.Abstractions" Version="21.0.29" />
<PackageReference Include="YamlDotNet" Version="15.3.0" />
</ItemGroup>

Expand Down
18 changes: 16 additions & 2 deletions Src/RandomizerTMF.Logic/RequestRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class RequestRules
public bool? InLatestAuthor { get; set; }
public bool? InLatestAwardedAuthor { get; set; }
public bool? InScreenshot { get; set; }
public bool? InUnlimiter { get; set; }
public DateOnly? UploadedBefore { get; set; }
public DateOnly? UploadedAfter { get; set; }
public TimeInt32? AuthorTimeMin { get; set; }
Expand Down Expand Up @@ -268,7 +269,7 @@ private static void AppendValue(StringBuilder b, Type type, object val, Type? ge
}
}

public void Serialize(BinaryWriter writer)
public void Serialize(BinaryWriter writer, int version)
{
writer.Write((int)Site);
writer.Write(EqualEnvironmentDistribution);
Expand Down Expand Up @@ -330,13 +331,19 @@ public void Serialize(BinaryWriter writer)
writer.Write(InLatestAuthor.HasValue ? Convert.ToByte(InLatestAuthor.Value) : (byte)255);
writer.Write(InLatestAwardedAuthor.HasValue ? Convert.ToByte(InLatestAwardedAuthor.Value) : (byte)255);
writer.Write(InScreenshot.HasValue ? Convert.ToByte(InScreenshot.Value) : (byte)255);

if (version >= 2)
{
writer.Write(InUnlimiter.HasValue ? Convert.ToByte(InUnlimiter.Value) : (byte)255);
}

writer.Write(UploadedBefore?.ToString("yyyy-MM-dd") ?? string.Empty);
writer.Write(UploadedAfter?.ToString("yyyy-MM-dd") ?? string.Empty);
writer.Write(AuthorTimeMin?.TotalMilliseconds ?? 0);
writer.Write(AuthorTimeMax?.TotalMilliseconds ?? 0);
}

public void Deserialize(BinaryReader r)
public void Deserialize(BinaryReader r, int version)
{
Site = (ESite)r.ReadInt32();
EqualEnvironmentDistribution = r.ReadBoolean();
Expand Down Expand Up @@ -420,6 +427,13 @@ public void Deserialize(BinaryReader r)
InLatestAwardedAuthor = inLatestAwardedAuthor == 255 ? null : Convert.ToBoolean(inLatestAwardedAuthor);
var inScreenshot = r.ReadByte();
InScreenshot = inScreenshot == 255 ? null : Convert.ToBoolean(inScreenshot);

if (version >= 2)
{
var inUnlimiter = r.ReadByte();
InUnlimiter = inUnlimiter == 255 ? null : Convert.ToBoolean(inUnlimiter);
}

var uploadedBefore = r.ReadString();
UploadedBefore = string.IsNullOrEmpty(uploadedBefore) ? null : DateOnly.Parse(uploadedBefore);
var uploadedAfter = r.ReadString();
Expand Down
32 changes: 20 additions & 12 deletions Src/RandomizerTMF.Logic/Services/MapDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class MapDownloader : IMapDownloader
private readonly IGbxService gbxService;
private readonly ILogger logger;

private readonly int requestMaxAttempts = 10;
private readonly int maxRequestMaxAttempts = 50;
private int requestAttempt;

public MapDownloader(IRandomizerEvents events,
Expand Down Expand Up @@ -108,17 +108,25 @@ public async Task<bool> PrepareNewMapAsync(Session currentSession, CancellationT
return false;
}

if (uint.TryParse(trackId, out var trackIdUint)
&& config.Rules.BannedMaps.TryGetValue(site, out var bannedTrackIds)
if (uint.TryParse(trackId, out var trackIdUint)
&& config.Rules.BannedMaps.TryGetValue(site, out var bannedTrackIds)
&& bannedTrackIds.Contains(trackIdUint))
{
logger.LogInformation("Track {trackId} is banned.", trackId);
return false;
}
{
logger.LogInformation("Track {trackId} is banned.", trackId);
return false;
}

var tmxLink = requestUri.ToString();

// With the ID, it is possible to immediately download the track Gbx and process it with GBX.NET
if (config.Rules.AvoidSkippedMaps && currentSession.SkippedMaps.Values.Any(x => x.TmxLink == tmxLink))
{
logger.LogInformation("Track {trackId} has been played already.", trackId);
return false;
}

// With the ID, it is possible to immediately download the track Gbx and process it with GBX.NET

using var trackGbxResponse = await DownloadMapByTrackIdAsync(requestUri.Host, trackId, cancellationToken);
using var trackGbxResponse = await DownloadMapByTrackIdAsync(requestUri.Host, trackId, cancellationToken);

var map = await GetMapFromResponseAsync(trackGbxResponse, cancellationToken);

Expand All @@ -136,8 +144,6 @@ public async Task<bool> PrepareNewMapAsync(Session currentSession, CancellationT

var mapSavePath = await SaveMapAsync(trackGbxResponse, map.MapUid, cancellationToken);

var tmxLink = requestUri.ToString();

currentSession.Map = new SessionMap(map, randomResponse.Headers.Date ?? DateTimeOffset.Now, tmxLink) // The map should be ready to be played now
{
FilePath = mapSavePath
Expand All @@ -152,7 +158,7 @@ public async Task<bool> PrepareNewMapAsync(Session currentSession, CancellationT
TmxLink = tmxLink,
});

discord.SessionMap(mapName, $"https://{requestUri.Host}/trackshow/{trackId}/image/1", map.Collection);
discord.SessionMap(mapName, $"https://{requestUri.Host}/trackshow/{trackId}/image/1", map.GetEnvironment());

return true;
}
Expand Down Expand Up @@ -274,6 +280,8 @@ internal async Task ValidateMapAsync(CGameCtnChallenge map, CancellationToken ca
await delayService.Delay(500, cancellationToken);
}

var requestMaxAttempts = Math.Min(config.ValidationRetries, maxRequestMaxAttempts);

Status($"Map is invalid (attempt {requestAttempt}/{requestMaxAttempts}).");

if (requestAttempt >= requestMaxAttempts)
Expand Down
9 changes: 8 additions & 1 deletion Src/RandomizerTMF.Logic/Services/RandomizerConfig.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using RandomizerTMF.Logic.Exceptions;
using System.IO.Abstractions;
using System.Reflection;
using YamlDotNet.Core;
Expand All @@ -18,6 +19,7 @@ public interface IRandomizerConfig
bool DisableAutosaveDetailScan { get; set; }
bool DisableAutoSkip { get; set; }
AutoSkipMode AutoSkipMode { get; set; }
int ValidationRetries { get; set; }
DiscordRichPresenceConfig DiscordRichPresence { get; set; }
bool TopSessions { get; set; }

Expand Down Expand Up @@ -59,6 +61,9 @@ public class RandomizerConfig : IRandomizerConfig
[YamlMember(Description = "When should automatic skip apply. Options are: AuthorMedal, GoldMedal, SilverMedal, BronzeMedal, Finished")]
public AutoSkipMode AutoSkipMode { get; set; }

[YamlMember(Description = "How many attempts to try before terminating the session if randomly picked map fails validation. Hardcoded maximum is 50.")]
public int ValidationRetries { get; set; } = 10;

[YamlMember(Description = "Discord Rich Presence configuration.")]
public DiscordRichPresenceConfig DiscordRichPresence { get; set; } = new();

Expand Down Expand Up @@ -97,16 +102,18 @@ public static RandomizerConfig GetOrCreate(ILogger logger, IFileSystem fileSyste
catch (YamlException ex)
{
logger.LogWarning(ex.InnerException, "Error while deserializing the config file ({configPath}; [{start}] - [{end}]).", Constants.ConfigYml, ex.Start, ex.End);
throw new ConfigCorruptedException("Config file is corrupted or incorrectly formatted.", ex);
}
catch (Exception ex)
{
logger.LogWarning(ex, "Error while deserializing the config file ({configPath}).", Constants.ConfigYml);
throw new ConfigCorruptedException("Config file is corrupted or there's another problem.", ex);
}
}

if (config is null)
{
logger.LogInformation("Config file not found or is corrupted, creating a new one...");
logger.LogInformation("Config file not found, creating a new one...");
config = new RandomizerConfig(logger, fileSystem);
}

Expand Down
4 changes: 2 additions & 2 deletions Src/RandomizerTMF.Logic/SessionData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public double GetScore()

public void Serialize(BinaryWriter writer)
{
const int version = 1;
const int version = 2;

writer.Write("RandTMF");
writer.Write((byte)version); // version
Expand Down Expand Up @@ -233,7 +233,7 @@ public void Deserialize(BinaryReader reader)
}

var version = reader.ReadByte();
if (version > 1)
if (version > 2)
{
throw new InvalidDataException("Invalid version.");
}
Expand Down
2 changes: 1 addition & 1 deletion Src/RandomizerTMF/RandomizerTMF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<PropertyGroup>
<Version>1.1.4</Version>
<Version>1.1.5</Version>
<PublishSingleFile>true</PublishSingleFile>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
</PropertyGroup>
Expand Down
13 changes: 13 additions & 0 deletions Src/RandomizerTMF/ViewModels/RequestRulesControlViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,19 @@ public DateTimeOffset? UploadedBefore
}
}

public bool NoUnlimiter
{
get => config.Rules.NoUnlimiter;
set
{
config.Rules.NoUnlimiter = value;

this.RaisePropertyChanged(nameof(NoUnlimiter));

config.Save();
}
}

public bool EqualEnvDistribution
{
get => config.Rules.RequestRules.EqualEnvironmentDistribution;
Expand Down
2 changes: 1 addition & 1 deletion Src/RandomizerTMF/ViewModels/SessionDataViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ private static void AddRuleString(IList rules, PropertyInfo prop, object owner)
}
else
{
val = null;
return;
}
}

Expand Down
2 changes: 1 addition & 1 deletion Src/RandomizerTMF/Views/RequestRulesControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@
<CheckBox IsChecked="{Binding MaxATEnabled}" ToolTip.Tip="Enable/disable maximal author time filter."/>
</StackPanel>

<CheckBox Grid.Row="6" Grid.Column="2" IsChecked="True" Content="No Unlimiter maps" ToolTip.Tip="Avoid maps made in TMUnlimiter. There will be an option for Unlimiter only maps once TMX receives an Unlimiter map filter."/>
<CheckBox Grid.Row="6" Grid.Column="2" IsChecked="{Binding NoUnlimiter}" Content="No Unlimiter maps" ToolTip.Tip="Avoid maps made in TMUnlimiter. There will be an option for Unlimiter only maps once TMX receives an Unlimiter map filter."/>

<TextBlock Grid.Column="3" HorizontalAlignment="Right" VerticalAlignment="Center">Map name:</TextBlock>
<TextBox Grid.Column="5" Text="{Binding MapName}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="21.0.22" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="21.0.29" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using Moq;
using RandomizerTMF.Logic.Exceptions;
using RandomizerTMF.Logic.Services;
using System.IO.Abstractions.TestingHelpers;

Expand Down Expand Up @@ -48,7 +49,7 @@ public void GetOrCreate_ExistingConfig_Read()
[Theory]
[InlineData(@"GameDirectory: [C:\GameDirectory")]
[InlineData("ReplayParseFailRetries: number")]
public void GetOrCreate_CorruptedConfig_Overwrite(string configContent)
public void GetOrCreate_CorruptedConfig_Throws(string configContent)
{
// Arrange
var mockLogger = new Mock<ILogger>();
Expand All @@ -59,16 +60,7 @@ public void GetOrCreate_CorruptedConfig_Overwrite(string configContent)
var lastWriteTime = fileSystem.File.GetLastWriteTime("Config.yml");
var defaultConfig = new RandomizerConfig();

// Act
var config = RandomizerConfig.GetOrCreate(mockLogger.Object, fileSystem);

// Assert
Assert.True(fileSystem.FileExists("Config.yml"));
Assert.NotEqual(expected: lastWriteTime, fileSystem.File.GetLastWriteTime("Config.yml"));
Assert.Equal(expected: defaultConfig.GameDirectory, actual: config.GameDirectory);
Assert.Equal(expected: defaultConfig.DownloadedMapsDirectory, actual: config.DownloadedMapsDirectory);
Assert.Equal(expected: defaultConfig.ReplayParseFailRetries, actual: config.ReplayParseFailRetries);
Assert.Equal(expected: defaultConfig.ReplayParseFailDelayMs, actual: config.ReplayParseFailDelayMs);
Assert.Equal(expected: defaultConfig.ReplayFileFormat, actual: config.ReplayFileFormat);
// Act & Assert
Assert.Throws<ConfigCorruptedException>(() => RandomizerConfig.GetOrCreate(mockLogger.Object, fileSystem));
}
}

0 comments on commit 881fea3

Please sign in to comment.