Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added showing patch notes to the main menu #4101

Merged
merged 25 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3424372
Added a tool for generating older release notes from Github directly
hhyyrylainen Feb 3, 2023
b2e7d01
Minified older patch notes like it should have been to take up slight…
hhyyrylainen Feb 6, 2023
2335f1f
Added loading of older and newer release patch notes
hhyyrylainen Feb 6, 2023
764aa11
Added component to save the last played Thrive version
hhyyrylainen Feb 6, 2023
1c0b384
Added AngleSharp to list of uses libraries
hhyyrylainen Feb 6, 2023
4612cfe
Basic patch notes display now works
hhyyrylainen Feb 6, 2023
367213b
Refactored ThriveFeedDisplayer.cs to be a bit nicer
hhyyrylainen Feb 6, 2023
c139cdf
Fixed invalid syntax from two commits ago
hhyyrylainen Feb 6, 2023
50f8761
Added the max path length variable back as it is needed in Steam mode
hhyyrylainen Feb 7, 2023
bf54221
Repositioned the store user name to the left side and removed the acc…
hhyyrylainen Feb 7, 2023
b7f81ea
Make main menu load the news feed always when it is enabled
hhyyrylainen Feb 7, 2023
fcbc653
Updated YamlDotNet
hhyyrylainen Feb 7, 2023
06a9b17
Adjusted the main menu to have the news and patch notes share the sam…
hhyyrylainen Feb 7, 2023
22f94a0
Fixed displaying the news feed again after it was hidden
hhyyrylainen Feb 7, 2023
277b0c2
Fixed LastPlayedVersion not updating in the current game state when s…
hhyyrylainen Feb 7, 2023
696ad0a
Fixed some main menu news feed and patch note display edge cases
hhyyrylainen Feb 7, 2023
2553516
Finished the patch note displayer logic
hhyyrylainen Feb 7, 2023
0752281
There's now an option to turn off the patch notes displaying
hhyyrylainen Feb 7, 2023
03633a2
Added support for plain links in markdown to bbcode converter
hhyyrylainen Feb 7, 2023
f2aadd9
Added a popup to display patch notes on button press in options menu
hhyyrylainen Feb 7, 2023
490d9c1
Added a tooltip for the button to view patch notes now
hhyyrylainen Feb 7, 2023
aecb1a3
Merge branch 'master' into 3868_patch_notes_in_game
hhyyrylainen Feb 7, 2023
224c892
Added checking to last played version number loading to ensure it is …
hhyyrylainen Feb 8, 2023
aaaf9e7
Fixed plain link conversion losing one preceding character
hhyyrylainen Feb 8, 2023
126e40b
Moved MarkCurrentVersionAsPlayed to main menu game enter callback
hhyyrylainen Feb 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ FastNoiseLite: MIT License Copyright(c) 2020 Jordan Peck ([email protected]),
Copyright(c) 2020 Contributors

Harmony: MIT License Copyright (c) 2017 Andreas Pardeike

AngleSharp: The MIT License (MIT) Copyright (c) 2013 - 2023 AngleSharp

YamlDotNet: MIT License Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Antoine Aubry and contributors

3 changes: 3 additions & 0 deletions Scripts/CodeChecks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public CodeChecks(Program.CheckOptions opts,
FilePathsToAlwaysIgnore.Add(new Regex(@"patrons\.json"));
FilePathsToAlwaysIgnore.Add(new Regex(@"translators\.json"));

// Generated json files that are intentionally minimized
FilePathsToAlwaysIgnore.Add(new Regex(@"older_patch_notes\.json$"));

// We ignore the .import files for now as checking those takes quite a bit of time
FilePathsToAlwaysIgnore.Add(new Regex(@"\.import$"));
}
Expand Down
283 changes: 283 additions & 0 deletions Scripts/FileGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
namespace Scripts;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Reflection;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using ScriptsBase.Utilities;
using SharedBase.Utilities;

public class FileGenerator
{
// TODO: share this constant with Thrive once a common module is created
public const string OLD_RELEASES_INFO_FILE = "simulation_parameters/common/older_patch_notes.json";

private const string GithubReleaseInfoPage = "https://api.github.com/repos/Revolutionary-Games/Thrive/releases";

private static readonly DateTime OldReleaseCutoffTime = new(2023, 1, 1);

private static readonly IReadOnlyCollection<Regex> PatchNotesStartRegexes = new[]
{
new Regex(@"# Patch Notes", RegexOptions.IgnoreCase),
new Regex(@"# New Features", RegexOptions.IgnoreCase),
new Regex(@"[\*#]+In this release:?[\*#\s]+", RegexOptions.IgnoreCase),
};

private static readonly Regex BulletPointRegex = new(@"^\s*[-\*]\s*(.+)$");

private Program.GeneratorOptions options;

public FileGenerator(Program.GeneratorOptions opts)
{
options = opts;
}

public async Task<int> Run(CancellationToken cancellationToken)
{
ColourConsole.WriteDebugLine($"Beginning generation with type: {options.Type}");

switch (options.Type)
{
case FileTypeToGenerate.List:
ColourConsole.WriteInfoLine("Available file types to generate:");

foreach (var value in Enum.GetValues<FileTypeToGenerate>())
{
// Skip the "help" option
if (value == FileTypeToGenerate.List)
continue;

ColourConsole.WriteNormalLine($" - {value.ToString()}");
}

return 0;
case FileTypeToGenerate.OldReleaseNotes:
if (!await DownloadAndWriteOldGithubReleases(cancellationToken))
return 1;

break;
default:
ColourConsole.WriteErrorLine($"Unhandled file type to generate: {options.Type}");
return 2;
}

ColourConsole.WriteSuccessLine($"Finished generating {options.Type}");
return 0;
}

private async Task<bool> DownloadAndWriteOldGithubReleases(CancellationToken cancellationToken)
{
ColourConsole.WriteInfoLine("Downloading release info from Github...");

using var client = SetupGithubClient();

var url = $"{GithubReleaseInfoPage}?per_page=100";

ColourConsole.WriteNormalLine($"Retrieving {url}");

/*var response = await client.GetAsync(url, cancellationToken);

var text = await response.Content.ReadAsStringAsync(cancellationToken);

ColourConsole.WriteInfoLine($"Got response: {text}");
response.EnsureSuccessStatusCode();*/

var releases = await client.GetFromJsonAsync<List<BasicGithubReleaseInfo>>(url, cancellationToken) ??
throw new NullDecodedJsonException();

// We intentionally don't handle having more than 100 releases here as this is just meant to grab the old
// releases, and once this is ran once, this script is not really needed again

// Filter out releases that don't belong in the old patch notes
releases = releases.Where(r => r.PublishedAt < OldReleaseCutoffTime).Reverse().ToList();

ColourConsole.WriteNormalLine("Processing data...");

var data = releases.ToDictionary(r => TagNameToReleaseName(r.TagName), ProcessGithubRelease);

ColourConsole.WriteNormalLine($"Writing {OLD_RELEASES_INFO_FILE}");

await JsonWriteHelper.WriteJsonWithBom(OLD_RELEASES_INFO_FILE, data, cancellationToken, false);

return true;
}

private string TagNameToReleaseName(string tag)
{
if (tag.StartsWith("v"))
tag = tag.Substring(1);

// Fix various wrong data
if (!tag.Contains('-') && tag.EndsWith("rc2"))
tag = tag.Substring(0, tag.Length - "rc2".Length) + "-rc2";

// Ensure we ended up with a good name by parsing it
try
{
Version.Parse(tag.Split("-", 2).First());

if (tag.Count(c => c == '-') > 1)
throw new Exception("Too many '-' characters in version number");
}
catch (Exception)
{
ColourConsole.WriteErrorLine($"Unknown format for version number: {tag}");
throw;
}

return tag;
}

private VersionPatchNotes ProcessGithubRelease(BasicGithubReleaseInfo releaseInfo)
{
var stringBuilder = new StringBuilder();

bool inPatchNotes = false;
bool inFirstParagraph = false;

bool seenFirstParagraph = false;

string? firstParagraph = null;
List<string> bulletPoints = new();

foreach (var line in releaseInfo.Body.ReplaceLineEndings().Split('\n'))
{
if (!seenFirstParagraph)
{
if (string.IsNullOrWhiteSpace(line))
continue;

seenFirstParagraph = true;
inFirstParagraph = true;
}

if (inFirstParagraph)
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
{
// First paragraph ended
inFirstParagraph = false;
firstParagraph = stringBuilder.ToString();
stringBuilder.Clear();

continue;
}

stringBuilder.Append(line);

// Markdown line endings count as spaces
stringBuilder.Append(' ');
continue;
}

if (inPatchNotes)
{
if ((string.IsNullOrWhiteSpace(line) || line.StartsWith("#")) && bulletPoints.Count > 0)
{
// Patch notes probably ended
inPatchNotes = false;
bulletPoints.Add(stringBuilder.ToString());
stringBuilder.Clear();

continue;
}

if (string.IsNullOrEmpty(line))
continue;

var match = BulletPointRegex.Match(line);

if (match.Success)
{
if (stringBuilder.Length > 0)
{
// End the previous bullet point
bulletPoints.Add(stringBuilder.ToString());
stringBuilder.Clear();
}

// A bullet point has started
stringBuilder.Append(match.Groups[1].Value);
}
else
{
stringBuilder.Append(line);
}

stringBuilder.Append(' ');
}

if (PatchNotesStartRegexes.Any(r => r.IsMatch(line)))
{
inPatchNotes = true;
}
}

if (stringBuilder.Length > 0 && bulletPoints.Count > 0)
bulletPoints.Add(stringBuilder.ToString());

if (firstParagraph == null)
throw new Exception("First paragraph not detected");

if (bulletPoints.Count < 1)
throw new Exception("No bullet points detected");

// Trim excess whitespace around the bullet points
bulletPoints = bulletPoints.Select(b => b.Trim()).ToList();

return new VersionPatchNotes(firstParagraph.Trim(), bulletPoints, releaseInfo.Link);
}

private HttpClient SetupGithubClient()
{
var client = new HttpClient();
SetUserAgent(client);

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json"));

return client;
}

private void SetUserAgent(HttpClient client)
{
var version = Assembly.GetEntryAssembly()?.GetName().Version ??
Assembly.GetExecutingAssembly().GetName().Version;

client.DefaultRequestHeaders.UserAgent.Clear();
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("ThriveScripts",
version?.ToString() ?? "unknown"));
}

/// <summary>
/// Just a few of the release fields we need for our use
/// </summary>
private class BasicGithubReleaseInfo
{
// ReSharper disable UnusedAutoPropertyAccessor.Local
[JsonPropertyName("tag_name")]
public string TagName { get; set; } = string.Empty;

public string Name { get; set; } = string.Empty;

public string Body { get; set; } = string.Empty;

[JsonPropertyName("html_url")]
public string Link { get; set; } = string.Empty;

[JsonPropertyName("created_at")]
public DateTime CreatedAt { get; set; }

[JsonPropertyName("published_at")]
public DateTime PublishedAt { get; set; }

// ReSharper restore UnusedAutoPropertyAccessor.Local
}
}
11 changes: 11 additions & 0 deletions Scripts/FileTypeToGenerate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Scripts;

public enum FileTypeToGenerate
{
/// <summary>
/// Just lists available types
/// </summary>
List,

OldReleaseNotes,
}
24 changes: 23 additions & 1 deletion Scripts/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static int Main(string[] args)
var result = CommandLineHelpers.CreateParser()
.ParseArguments<CheckOptions, TestOptions, ChangesOptions, LocalizationOptions, CleanupOptions,
PackageOptions, UploadOptions, ContainerOptions, SteamOptions, GodotTemplateOptions,
TranslationProgressOptions, CreditsOptions>(args)
TranslationProgressOptions, CreditsOptions, GeneratorOptions>(args)
.MapResult(
(CheckOptions options) => RunChecks(options),
(TestOptions options) => RunTests(options),
Expand All @@ -30,6 +30,7 @@ public static int Main(string[] args)
(GodotTemplateOptions options) => RunTemplateInstall(options),
(TranslationProgressOptions options) => RunTranslationProgress(options),
(CreditsOptions options) => RunCreditsUpdate(options),
(GeneratorOptions options) => RunFileGenerator(options),
CommandLineHelpers.PrintCommandLineErrors);

ConsoleHelpers.CleanConsoleStateForExit();
Expand Down Expand Up @@ -215,6 +216,19 @@ private static int RunCreditsUpdate(CreditsOptions options)
return CreditsUpdater.Run(tokenSource.Token).Result ? 0 : 1;
}

private static int RunFileGenerator(GeneratorOptions options)
{
CommandLineHelpers.HandleDefaultOptions(options);

ColourConsole.WriteDebugLine("Running file generating tool");

var tokenSource = ConsoleHelpers.CreateSimpleConsoleCancellationSource();

var tool = new FileGenerator(options);

return tool.Run(tokenSource.Token).Result;
}

public class CheckOptions : CheckOptionsBase
{
}
Expand Down Expand Up @@ -309,4 +323,12 @@ public class TranslationProgressOptions : ScriptOptionsBase
public class CreditsOptions : ScriptOptionsBase
{
}

[Verb("generate", HelpText = "Generates various kinds of files")]
public class GeneratorOptions : ScriptOptionsBase
{
[Value(0, MetaName = "TYPE", Required = true,
HelpText = "Which type of file to generate ('List' prints a list of available types)")]
public FileTypeToGenerate Type { get; set; }
}
}
1 change: 1 addition & 0 deletions Scripts/TranslationProgressTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

public static class TranslationProgressTool
{
// TODO: share this constant with Thrive once a common module is created
public const string TRANSLATIONS_PROGRESS_FILE = "simulation_parameters/common/translations_info.json";

public static async Task<bool> Run(CancellationToken cancellationToken)
Expand Down
19 changes: 19 additions & 0 deletions Scripts/VersionPatchNotes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Scripts;

using System.Collections.Generic;

public class VersionPatchNotes
{
public VersionPatchNotes(string introductionText, List<string> patchNotes, string releaseLink)
{
IntroductionText = introductionText;
PatchNotes = patchNotes;
ReleaseLink = releaseLink;
}

public string IntroductionText { get; }

public List<string> PatchNotes { get; }

public string ReleaseLink { get; }
}
Loading