mirror of
https://github.com/RPCS3/discord-bot.git
synced 2024-12-03 16:32:37 +00:00
commit
1c0ca170c5
@ -24,6 +24,7 @@ namespace AppveyorClient
|
||||
private static readonly ProductInfoHeaderValue ProductInfoHeader = new ProductInfoHeaderValue("RPCS3CompatibilityBot", "2.0");
|
||||
private static readonly TimeSpan CacheTime = TimeSpan.FromDays(1);
|
||||
private static readonly TimeSpan JobToBuildCacheTime = TimeSpan.FromDays(30);
|
||||
private static readonly TimeSpan MasterBuildCacheTime = TimeSpan.FromDays(1);
|
||||
private static readonly TimeSpan JobIdSearchThreshold = TimeSpan.FromDays(6 * 30);
|
||||
private static readonly MemoryCache ResponseCache = new MemoryCache(new MemoryCacheOptions {ExpirationScanFrequency = TimeSpan.FromHours(1)});
|
||||
|
||||
@ -170,6 +171,7 @@ namespace AppveyorClient
|
||||
{
|
||||
if (ResponseCache.TryGetValue(jobId, out Build result))
|
||||
return result;
|
||||
|
||||
try
|
||||
{
|
||||
var oldestBuildDate = DateTime.UtcNow - JobIdSearchThreshold;
|
||||
@ -232,6 +234,34 @@ namespace AppveyorClient
|
||||
return o;
|
||||
}
|
||||
|
||||
public async Task<Build> GetMasterBuildAsync(string commit, DateTime? mergeDate, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(commit))
|
||||
return null;
|
||||
|
||||
if (ResponseCache.TryGetValue(commit, out Build result))
|
||||
return result;
|
||||
|
||||
try
|
||||
{
|
||||
mergeDate = mergeDate ?? (DateTime.UtcNow - JobIdSearchThreshold);
|
||||
result = await FindBuildAsync(
|
||||
h => h.Builds.Last().Created > mergeDate,
|
||||
b => b.CommitId.StartsWith(commit, StringComparison.InvariantCultureIgnoreCase) && b.Status == "success",
|
||||
cancellationToken
|
||||
);
|
||||
if (result != null)
|
||||
ResponseCache.Set(commit, result, MasterBuildCacheTime);
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ApiConfig.Log.Error(e);
|
||||
}
|
||||
ApiConfig.Log.Debug($"Failed to find master {nameof(Build)} for commit {commit}");
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<Build> FindBuildAsync(Func<HistoryInfo, bool> takePredicate, Func<Build, bool> selectPredicate, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
|
@ -16,6 +16,7 @@ namespace AppveyorClient.POCOs
|
||||
public DateTime? Finished;
|
||||
public List<Job> Jobs;
|
||||
public string Message;
|
||||
public string CommitId;
|
||||
public string PullRequestHeadBranch;
|
||||
public string PullRequestHeadCommitId;
|
||||
public string PullRequestHeadRepository;
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
public class BuildInfo
|
||||
{
|
||||
public string Pr;
|
||||
public int? Pr;
|
||||
public string Datetime;
|
||||
public BuildLink Windows;
|
||||
public BuildLink Linux;
|
||||
|
@ -150,8 +150,10 @@ Example usage:
|
||||
CachedUpdateInfo = info;
|
||||
if (channel != null)
|
||||
await channel.SendMessageAsync(embed: embed.Build()).ConfigureAwait(false);
|
||||
var updateLinks = info?.LatestBuild?.Pr;
|
||||
if (!string.IsNullOrEmpty(updateLinks) && lastUpdateInfo != updateLinks && updateCheck.Wait(0))
|
||||
var updateLinks = info?.LatestBuild?.Pr?.ToString();
|
||||
if (!string.IsNullOrEmpty(updateLinks)
|
||||
&& lastUpdateInfo != updateLinks
|
||||
&& updateCheck.Wait(0))
|
||||
try
|
||||
{
|
||||
var compatChannel = await discordClient.GetChannelAsync(Config.BotChannelId).ConfigureAwait(false);
|
||||
@ -162,6 +164,7 @@ Example usage:
|
||||
return false;
|
||||
}
|
||||
|
||||
embed.Title = $"[New Update] {embed.Title}";
|
||||
await compatChannel.SendMessageAsync(embed: embed.Build()).ConfigureAwait(false);
|
||||
lastUpdateInfo = updateLinks;
|
||||
using (var db = new BotDb())
|
||||
|
@ -14,7 +14,7 @@ namespace CompatBot.EventHandlers
|
||||
internal static class IsTheGamePlayableHandler
|
||||
{
|
||||
private const RegexOptions DefaultOptions = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture;
|
||||
private static readonly Regex GameNameStatusMention = new Regex(@"((is|does|can I play)\s+|(?<dumb>^))(?<game_title>.+?)(\s+((now|currently)\s+)?((is )?playable|work(s|ing)?)(?(dumb)\?))", DefaultOptions);
|
||||
private static readonly Regex GameNameStatusMention = new Regex(@"((is|does|can I play)\s+|(?<dumb>^))(?<game_title>.+?)(\s+((now|currently|at all|possibly)\s+)?((is )?playable|work(s|ing)?)(?(dumb)\?))", DefaultOptions);
|
||||
private static readonly ConcurrentDictionary<ulong, DateTime> CooldownBuckets = new ConcurrentDictionary<ulong, DateTime>();
|
||||
private static readonly TimeSpan CooldownThreshold = TimeSpan.FromSeconds(5);
|
||||
private static readonly Client Client = new Client();
|
||||
@ -67,10 +67,12 @@ namespace CompatBot.EventHandlers
|
||||
{
|
||||
var requestBuilder = RequestBuilder.Start().SetSearch(gameTitle);
|
||||
var status = await Client.GetCompatResultAsync(requestBuilder, Config.Cts.Token).ConfigureAwait(false);
|
||||
if (status.ReturnCode == 0 && status.Results.Any())
|
||||
if ((status.ReturnCode == 0 || status.ReturnCode == 2) && status.Results.Any())
|
||||
{
|
||||
var info = status.GetSortedList().First().Value;
|
||||
if (CompatApiResultUtils.GetScore(gameTitle, info) < 0.2)
|
||||
var score = CompatApiResultUtils.GetScore(gameTitle, info);
|
||||
Config.Log.Debug($"Looked up \"{gameTitle}\", got \"{info.Title}\" with score {score}");
|
||||
if (score < 0.2)
|
||||
return;
|
||||
|
||||
var botSpamChannel = await args.Client.GetChannelAsync(Config.BotSpamId).ConfigureAwait(false);
|
||||
|
@ -23,11 +23,13 @@ namespace CompatBot.EventHandlers
|
||||
if (args.Author.IsBot)
|
||||
return;
|
||||
|
||||
#if !DEBUG
|
||||
if (!args.Channel.Name.Equals("help", StringComparison.InvariantCultureIgnoreCase))
|
||||
return;
|
||||
|
||||
if (DateTime.UtcNow - lastMention < ThrottlingThreshold)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (string.IsNullOrEmpty(args.Message.Content) || args.Message.Content.StartsWith(Config.CommandPrefix))
|
||||
return;
|
||||
@ -42,7 +44,7 @@ namespace CompatBot.EventHandlers
|
||||
{
|
||||
var explanation = await GetLogUploadExplanationAsync().ConfigureAwait(false);
|
||||
|
||||
var lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, 15).ConfigureAwait(false);
|
||||
var lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, 10).ConfigureAwait(false);
|
||||
foreach (var msg in lastBotMessages)
|
||||
if (BotShutupHandler.NeedToSilence(msg).needToChill
|
||||
|| (msg.Author.IsCurrent && msg.Content == explanation))
|
||||
|
@ -11,6 +11,7 @@ namespace CompatBot.Utils.ResultFormatters
|
||||
internal static class UpdateInfoFormatter
|
||||
{
|
||||
private static readonly GithubClient.Client githubClient = new GithubClient.Client();
|
||||
private static readonly AppveyorClient.Client appveyorClient = new AppveyorClient.Client();
|
||||
|
||||
public static async Task<DiscordEmbedBuilder> AsEmbedAsync(this UpdateInfo info, DiscordEmbedBuilder builder = null)
|
||||
{
|
||||
@ -18,41 +19,63 @@ namespace CompatBot.Utils.ResultFormatters
|
||||
return builder ?? new DiscordEmbedBuilder {Title = "Error", Description = "Error communicating with the update API. Try again later.", Color = Config.Colors.Maintenance};
|
||||
|
||||
var justAppend = builder != null;
|
||||
var build = info.LatestBuild;
|
||||
var pr = build?.Pr ?? "0";
|
||||
var latestBuild = info.LatestBuild;
|
||||
var latestPr = latestBuild?.Pr;
|
||||
var currentPr = info.CurrentBuild?.Pr;
|
||||
string url = null;
|
||||
PrInfo prInfo = null;
|
||||
PrInfo latestPrInfo = null;
|
||||
PrInfo currentPrInfo = null;
|
||||
|
||||
string prDesc = "";
|
||||
if (!justAppend)
|
||||
{
|
||||
if (int.TryParse(pr, out var prNum) && prNum > 0)
|
||||
if (latestPr > 0)
|
||||
{
|
||||
prInfo = await githubClient.GetPrInfoAsync(prNum, Config.Cts.Token).ConfigureAwait(false);
|
||||
url = prInfo?.HtmlUrl ?? "https://github.com/RPCS3/rpcs3/pull/" + pr;
|
||||
pr = $"PR #{pr} by {prInfo?.User?.Login ?? "???"}";
|
||||
latestPrInfo = await githubClient.GetPrInfoAsync(latestPr.Value, Config.Cts.Token).ConfigureAwait(false);
|
||||
url = latestPrInfo?.HtmlUrl ?? "https://github.com/RPCS3/rpcs3/pull/" + latestPr;
|
||||
prDesc = $"PR #{latestPr} by {latestPrInfo?.User?.Login ?? "???"}";
|
||||
}
|
||||
else
|
||||
pr = "PR #???";
|
||||
prDesc = "PR #???";
|
||||
|
||||
if (currentPr > 0 && currentPr != latestPr)
|
||||
currentPrInfo = await githubClient.GetPrInfoAsync(currentPr.Value, Config.Cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
builder = builder ?? new DiscordEmbedBuilder {Title = pr, Url = url, Description = prInfo?.Title, Color = Config.Colors.DownloadLinks};
|
||||
if (!string.IsNullOrEmpty(build?.Datetime))
|
||||
builder = builder ?? new DiscordEmbedBuilder {Title = prDesc, Url = url, Description = latestPrInfo?.Title, Color = Config.Colors.DownloadLinks};
|
||||
var currentCommit = currentPrInfo?.MergeCommitSha;
|
||||
var latestCommit = latestPrInfo?.MergeCommitSha;
|
||||
var currentAppveyorBuild = await appveyorClient.GetMasterBuildAsync(currentCommit, currentPrInfo?.MergedAt, Config.Cts.Token).ConfigureAwait(false);
|
||||
var latestAppveyorBuild = await appveyorClient.GetMasterBuildAsync(latestCommit, latestPrInfo?.MergedAt, Config.Cts.Token).ConfigureAwait(false);
|
||||
var buildTimestampKind = "Build";
|
||||
var latestBuildTimestamp = latestAppveyorBuild?.Finished?.ToUniversalTime();
|
||||
var currentBuildTimestamp = currentAppveyorBuild?.Finished?.ToUniversalTime();
|
||||
if (!latestBuildTimestamp.HasValue)
|
||||
{
|
||||
var timestampInfo = build.Datetime;
|
||||
if (info.CurrentBuild?.Pr is string buildPr
|
||||
&& buildPr != info.LatestBuild?.Pr
|
||||
&& GetUpdateDelta(info) is TimeSpan timeDelta)
|
||||
buildTimestampKind = "Merge";
|
||||
latestBuildTimestamp = latestPrInfo?.MergedAt;
|
||||
currentBuildTimestamp = currentPrInfo?.MergedAt;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(latestBuild?.Datetime))
|
||||
{
|
||||
var timestampInfo = latestBuildTimestamp?.ToString("u") ?? latestBuild.Datetime;
|
||||
if (currentPr > 0
|
||||
&& currentPr != latestPr
|
||||
&& GetUpdateDelta(latestBuildTimestamp, currentBuildTimestamp) is TimeSpan timeDelta)
|
||||
timestampInfo += $" ({timeDelta.AsTimeDeltaDescription()} newer)";
|
||||
else if (!justAppend && DateTime.TryParse(build.Datetime, out var buildDateTime) && DateTime.UtcNow.Ticks > buildDateTime.Ticks)
|
||||
timestampInfo += $" ({(DateTime.UtcNow - buildDateTime.AsUtc()).AsTimeDeltaDescription()} ago)";
|
||||
else if (!justAppend
|
||||
&& latestBuildTimestamp.HasValue
|
||||
&& DateTime.UtcNow.Ticks > latestBuildTimestamp.Value.Ticks)
|
||||
timestampInfo += $" ({(DateTime.UtcNow - latestBuildTimestamp.Value).AsTimeDeltaDescription()} ago)";
|
||||
|
||||
if (justAppend)
|
||||
builder.AddField($"Latest master build ({timestampInfo})", "This pull request has been merged, and is a part of `master` now");
|
||||
else
|
||||
builder.AddField("Merge timestamp", timestampInfo);
|
||||
builder.AddField($"{buildTimestampKind} timestamp", timestampInfo);
|
||||
}
|
||||
return builder
|
||||
.AddField("Windows ".FixSpaces(), GetLinkMessage(build?.Windows?.Download, true), true)
|
||||
.AddField("Linux ".FixSpaces(), GetLinkMessage(build?.Linux?.Download, true), true);
|
||||
.AddField("Windows ".FixSpaces(), GetLinkMessage(latestBuild?.Windows?.Download, true), true)
|
||||
.AddField("Linux ".FixSpaces(), GetLinkMessage(latestBuild?.Linux?.Download, true), true);
|
||||
}
|
||||
|
||||
private static string GetLinkMessage(string link, bool simpleName)
|
||||
@ -69,6 +92,13 @@ namespace CompatBot.Utils.ResultFormatters
|
||||
return $"[⏬ {text}]({link}){" ".FixSpaces()}";
|
||||
}
|
||||
|
||||
public static TimeSpan? GetUpdateDelta(DateTime? latest, DateTime? current)
|
||||
{
|
||||
if (latest.HasValue && current.HasValue)
|
||||
return latest - current;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static TimeSpan? GetUpdateDelta(this UpdateInfo updateInfo)
|
||||
{
|
||||
if (updateInfo?.LatestBuild?.Datetime is string latestDateTimeStr
|
||||
|
@ -13,6 +13,7 @@ namespace GithubClient.POCOs
|
||||
public DateTime? UpdatedAt;
|
||||
public DateTime? ClosedAt;
|
||||
public DateTime? MergedAt;
|
||||
public string MergeCommitSha;
|
||||
public string StatusesUrl;
|
||||
public int Additions;
|
||||
public int Deletions;
|
||||
|
Loading…
Reference in New Issue
Block a user