-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathSudo.Fix.cs
168 lines (154 loc) · 7.79 KB
/
Sudo.Fix.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
using System.Text.RegularExpressions;
using CompatBot.Database;
using CompatBot.Database.Providers;
using DSharpPlus.Commands.Processors.TextCommands;
namespace CompatBot.Commands;
internal static partial class Sudo
{
// '2018-06-09 08:20:44.968000 - '
// '2018-07-19T12:19:06.7888609Z - '
[GeneratedRegex(@"^(?<cutout>(?<date>\d{4}-\d\d-\d\d[ T][0-9:\.]+Z?) - )", RegexOptions.ExplicitCapture | RegexOptions.Singleline)]
private static partial Regex Timestamp();
[GeneratedRegex(@"(?<id><#\d+>)", RegexOptions.ExplicitCapture | RegexOptions.Singleline)]
private static partial Regex Channel();
[Command("fix"), RequiresDm]
[Description("Commands to fix various stuff")]
internal static class Fix
{
[Command("timestamps")]
[Description("Fix `timestamp` column in the `warning` table")]
public static async ValueTask Timestamps(TextCommandContext ctx)
{
try
{
var @fixed = 0;
await using var wdb = await BotDb.OpenWriteAsync().ConfigureAwait(false);
foreach (var warning in wdb.Warning)
if (!string.IsNullOrEmpty(warning.FullReason))
{
var match = Timestamp().Match(warning.FullReason);
if (match.Success && DateTime.TryParse(match.Groups["date"].Value, out var timestamp))
{
warning.Timestamp = timestamp.Ticks;
warning.FullReason = warning.FullReason[(match.Groups["cutout"].Value.Length)..];
@fixed++;
}
}
await wdb.SaveChangesAsync().ConfigureAwait(false);
await ctx.Channel.SendMessageAsync($"Fixed {@fixed} records").ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Warn(e, "Couldn't fix warning timestamps");
await ctx.Channel.SendMessageAsync("Failed to fix warning timestamps").ConfigureAwait(false);
}
}
[Command("channels")]
[Description("Fixes channel mentions in `warning` table")]
public static async ValueTask Channels(TextCommandContext ctx)
{
try
{
var @fixed = 0;
await using var wdb = await BotDb.OpenWriteAsync().ConfigureAwait(false);
foreach (var warning in wdb.Warning)
{
var newReason = await FixChannelMentionAsync(ctx, warning.Reason).ConfigureAwait(false);
if (newReason != warning.Reason && newReason != null)
{
warning.Reason = newReason;
@fixed++;
}
}
await wdb.SaveChangesAsync().ConfigureAwait(false);
await ctx.Channel.SendMessageAsync($"Fixed {@fixed} records").ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Warn(e, "Couldn't fix channel mentions");
await ctx.Channel.SendMessageAsync("Failed to fix warning timestamps").ConfigureAwait(false);
}
}
[Command("syscalls")]
[Description("Fixes invalid function names in `syscall-info` table and associated data")]
public static async ValueTask Syscalls(TextCommandContext ctx)
{
try
{
await ctx.Channel.SendMessageAsync("Fixing invalid function names…").ConfigureAwait(false);
var result = await SyscallInfoProvider.FixInvalidFunctionNamesAsync().ConfigureAwait(false);
if (result.funcs > 0)
await ctx.Channel.SendMessageAsync($"Successfully fixed {result.funcs} function name{(result.funcs == 1 ? "" : "s")} and {result.links} game link{(result.links == 1 ? "" : "s")}").ConfigureAwait(false);
else
await ctx.Channel.SendMessageAsync("No invalid syscall functions detected").ConfigureAwait(false);
await ctx.Channel.SendMessageAsync("Fixing duplicates…").ConfigureAwait(false);
result = await SyscallInfoProvider.FixDuplicatesAsync().ConfigureAwait(false);
if (result.funcs > 0)
await ctx.Channel.SendMessageAsync($"Successfully merged {result.funcs} function{(result.funcs == 1 ? "" : "s")} and {result.links} game link{(result.links == 1 ? "" : "s")}").ConfigureAwait(false);
else
await ctx.Channel.SendMessageAsync("No duplicate function entries found").ConfigureAwait(false);
}
catch (Exception e)
{
Config.Log.Warn(e, "Failed to fix syscall info");
await ctx.ReactWithAsync(Config.Reactions.Failure, "Failed to fix syscall information", true).ConfigureAwait(false);
}
}
[Command("title_marks"), TextAlias("trademarks", "tms")]
[Description("Strips trade marks and similar cruft from game titles in local database")]
public static async ValueTask TitleMarks(TextCommandContext ctx)
{
var changed = 0;
await using var wdb = await ThumbnailDb.OpenWriteAsync().ConfigureAwait(false);
foreach (var thumb in wdb.Thumbnail)
{
if (string.IsNullOrEmpty(thumb.Name))
continue;
var newTitle = thumb.Name.StripMarks();
if (newTitle.EndsWith("full game", StringComparison.OrdinalIgnoreCase))
newTitle = newTitle[..^10];
if (newTitle.EndsWith("full game unlock", StringComparison.OrdinalIgnoreCase))
newTitle = newTitle[..^17];
if (newTitle.EndsWith("downloadable game", StringComparison.OrdinalIgnoreCase))
newTitle = newTitle[..^18];
newTitle = newTitle.TrimEnd();
if (newTitle == thumb.Name)
continue;
changed++;
thumb.Name = newTitle;
}
await wdb.SaveChangesAsync();
await ctx.Channel.SendMessageAsync($"Fixed {changed} title{(changed == 1 ? "" : "s")}").ConfigureAwait(false);
}
[Command("metacritic_links"), TextAlias("mcl")]
[Description("Cleans up Metacritic links")]
public static async ValueTask MetacriticLinks(TextCommandContext ctx, [Description("Remove links for trial and demo versions only")] bool demosOnly = true)
{
var changed = 0;
await using var wdb = await ThumbnailDb.OpenWriteAsync().ConfigureAwait(false);
foreach (var thumb in wdb.Thumbnail.Where(t => t.MetacriticId != null))
{
if (demosOnly
&& thumb.Name != null
&& !CompatList.TrialNamePattern().IsMatch(thumb.Name))
continue;
thumb.MetacriticId = null;
changed++;
}
await wdb.SaveChangesAsync();
await ctx.Channel.SendMessageAsync($"Fixed {changed} title{(changed == 1 ? "" : "s")}").ConfigureAwait(false);
}
private static async ValueTask<string?> FixChannelMentionAsync(TextCommandContext ctx, string? msg)
{
if (msg is not {Length: >0})
return msg;
var entries = Channel().Matches(msg).Select(m => m.Groups["id"].Value).Distinct().ToList();
if (entries.Count is 0)
return msg;
foreach (var channel in entries)
if (await ctx.ParseChannelNameAsync(channel).ConfigureAwait(false) is {} ch)
msg = msg.Replace(channel, "#" + ch.Name);
return msg;
}
}
}