Skip to content

Commit 9ae0c72

Browse files
feat: disabling known bots
1 parent 42d5ccf commit 9ae0c72

File tree

1 file changed

+198
-198
lines changed

1 file changed

+198
-198
lines changed
Lines changed: 198 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -1,198 +1,198 @@
1-
using System.Collections.Immutable;
2-
using System.Diagnostics;
3-
using System.Text;
4-
5-
using Newtonsoft.Json;
6-
7-
using Nullinside.Api.Common.Twitch;
8-
using Nullinside.Api.Model;
9-
using Nullinside.Api.Model.Ddl;
10-
using Nullinside.Api.TwitchBot.Model;
11-
12-
using TwitchLib.Api.Helix.Models.Chat.GetChatters;
13-
14-
using TwitchUserConfig = Nullinside.Api.Model.Ddl.TwitchUserConfig;
15-
16-
namespace Nullinside.Api.TwitchBot.Bots;
17-
18-
/// <summary>
19-
/// Searches for and bans known bots when they enter the chat.
20-
/// </summary>
21-
public class BanKnownBots : ABotRule {
22-
/// <summary>
23-
/// Handles refreshing the <see cref="KnownBotListUsername" /> collection.
24-
/// </summary>
25-
private static Task _ = Task.Run(async () => {
26-
while (true) {
27-
Task<ImmutableHashSet<string>?> twitchInsights = GetTwitchInsightsBots();
28-
Task<ImmutableHashSet<string>?> commanderRoot = GetCommanderRootBots();
29-
await Task.WhenAll(twitchInsights, commanderRoot);
30-
if (null != twitchInsights.Result) {
31-
KnownBotListUsername = twitchInsights.Result;
32-
}
33-
34-
if (null != commanderRoot.Result) {
35-
KnownBotListUserId = commanderRoot.Result;
36-
}
37-
38-
// The list is enormous, force garbage collection.
39-
GC.Collect();
40-
GC.WaitForPendingFinalizers();
41-
await Task.Delay(TimeSpan.FromMinutes(10));
42-
}
43-
});
44-
45-
/// <summary>
46-
/// The cache of known bots.
47-
/// </summary>
48-
public static ImmutableHashSet<string>? KnownBotListUsername { get; set; }
49-
50-
/// <summary>
51-
/// The cache of known bots.
52-
/// </summary>
53-
public static ImmutableHashSet<string>? KnownBotListUserId { get; set; }
54-
55-
/// <summary>
56-
/// Determine if the rule is enabled in the configuration.
57-
/// </summary>
58-
/// <param name="config">The user's configuration.</param>
59-
/// <returns>True if it should run, false otherwise.</returns>
60-
public override bool ShouldRun(TwitchUserConfig config) {
61-
return config is { Enabled: true, BanKnownBots: true };
62-
}
63-
64-
/// <summary>
65-
/// Searches for and bans known bots when they enter the chat.
66-
/// </summary>
67-
/// <param name="user">The user.</param>
68-
/// <param name="config">The user's configuration.</param>
69-
/// <param name="botProxy">The twitch api authenticated as the bot user.</param>
70-
/// <param name="db">The database.</param>
71-
/// <param name="stoppingToken">The cancellation token.</param>
72-
public override async Task Handle(User user, TwitchUserConfig config, ITwitchApiProxy botProxy,
73-
INullinsideContext db, CancellationToken stoppingToken = new()) {
74-
if (null == user.TwitchId) {
75-
return;
76-
}
77-
78-
// TODO: SKIP MODS AND VIPS
79-
80-
// Get the list of people in the chat.
81-
List<Chatter>? chatters =
82-
(await botProxy.GetChannelUsers(user.TwitchId, Constants.BotId, stoppingToken))?.ToList();
83-
if (null == chatters || chatters.Count == 0) {
84-
return;
85-
}
86-
87-
// Perform the comparison in the lock to prevent multithreading issues.
88-
// The collection is extremely large so we do not want to make a copy of it.
89-
var botsInChatInsights = new List<Chatter>();
90-
var botsInChatCommanderRoot = new List<Chatter>();
91-
ImmutableHashSet<string>? knownBotUsernames = KnownBotListUsername;
92-
ImmutableHashSet<string>? knownBotUserIds = KnownBotListUserId;
93-
94-
if (null != knownBotUsernames) {
95-
botsInChatInsights.AddRange(chatters.Where(k =>
96-
knownBotUsernames.Contains(k.UserLogin.ToLowerInvariant())));
97-
}
98-
99-
if (null != knownBotUserIds) {
100-
botsInChatCommanderRoot.AddRange(chatters.Where(k =>
101-
knownBotUserIds.Contains(k.UserId.ToLowerInvariant())));
102-
}
103-
104-
// Remove the whitelisted bots
105-
botsInChatInsights = botsInChatInsights
106-
.Where(b => !Constants.WhitelistedBots.Contains(b.UserLogin.ToLowerInvariant())).ToList();
107-
botsInChatCommanderRoot = botsInChatCommanderRoot
108-
.Where(b => !Constants.WhitelistedBots.Contains(b.UserLogin.ToLowerInvariant())).ToList();
109-
110-
// Ban them.
111-
if (botsInChatInsights.Count != 0) {
112-
await BanOnce(botProxy, db, user.TwitchId, botsInChatInsights.Select(b => (Id: b.UserId, Username: b.UserLogin)),
113-
"[Bot] Username on Known Bot List", stoppingToken);
114-
}
115-
116-
if (botsInChatCommanderRoot.Count != 0) {
117-
await BanOnce(botProxy, db, user.TwitchId,
118-
botsInChatCommanderRoot.Select(b => (Id: b.UserId, Username: b.UserLogin)),
119-
"[Bot] Username on Known Bot List", stoppingToken);
120-
}
121-
}
122-
123-
/// <summary>
124-
/// Gets the list of all known bots.
125-
/// </summary>
126-
/// <returns>The list of bots if successful, null otherwise.</returns>
127-
private static async Task<ImmutableHashSet<string>?> GetTwitchInsightsBots() {
128-
var stopwatch = new Stopwatch();
129-
stopwatch.Start();
130-
// Reach out to the api and find out what bots are online.
131-
using var http = new HttpClient();
132-
HttpResponseMessage response = await http.GetAsync("https://api.twitchinsights.net/v1/bots/all");
133-
if (!response.IsSuccessStatusCode) {
134-
return null;
135-
}
136-
137-
byte[]? content = await response.Content.ReadAsByteArrayAsync();
138-
string? jsonString = Encoding.UTF8.GetString(content);
139-
var liveBotsResponse = JsonConvert.DeserializeObject<TwitchInsightsLiveBotsResponse>(jsonString);
140-
if (null == liveBotsResponse) {
141-
return null;
142-
}
143-
144-
ImmutableHashSet<string> allBots = liveBotsResponse.bots
145-
.Where(s => !string.IsNullOrWhiteSpace(s[0].ToString()))
146-
#pragma warning disable 8602
147-
.Select(s => s[0].ToString().ToLowerInvariant())
148-
#pragma warning restore 8602
149-
.ToImmutableHashSet();
150-
151-
foreach (List<object>? list in liveBotsResponse.bots) {
152-
list.Clear();
153-
}
154-
155-
liveBotsResponse.bots.Clear();
156-
liveBotsResponse.bots = null;
157-
liveBotsResponse = null;
158-
content = null;
159-
jsonString = null;
160-
return allBots;
161-
}
162-
163-
/// <summary>
164-
/// Gets the list of all known bots.
165-
/// </summary>
166-
/// <returns>The list of bots if successful, null otherwise.</returns>
167-
private static async Task<ImmutableHashSet<string>?> GetCommanderRootBots() {
168-
var stopwatch = new Stopwatch();
169-
stopwatch.Start();
170-
// Reach out to the api and find out what bots are online.
171-
using var http = new HttpClient();
172-
using HttpResponseMessage response =
173-
await http.GetAsync("https://twitch-tools.rootonline.de/blocklist_manager.php?preset=known_bot_users");
174-
if (!response.IsSuccessStatusCode) {
175-
return null;
176-
}
177-
178-
byte[]? content = await response.Content.ReadAsByteArrayAsync();
179-
string? jsonString = Encoding.UTF8.GetString(content);
180-
var liveBotsResponse = JsonConvert.DeserializeObject<List<string>>(jsonString);
181-
if (null == liveBotsResponse) {
182-
return null;
183-
}
184-
185-
ImmutableHashSet<string> allBots = liveBotsResponse
186-
#pragma warning disable 8602
187-
.Select(s => s.ToLowerInvariant())
188-
#pragma warning restore 8602
189-
.ToImmutableHashSet();
190-
191-
liveBotsResponse.Clear();
192-
liveBotsResponse = null;
193-
liveBotsResponse = null;
194-
content = null;
195-
jsonString = null;
196-
return allBots;
197-
}
198-
}
1+
// using System.Collections.Immutable;
2+
// using System.Diagnostics;
3+
// using System.Text;
4+
//
5+
// using Newtonsoft.Json;
6+
//
7+
// using Nullinside.Api.Common.Twitch;
8+
// using Nullinside.Api.Model;
9+
// using Nullinside.Api.Model.Ddl;
10+
// using Nullinside.Api.TwitchBot.Model;
11+
//
12+
// using TwitchLib.Api.Helix.Models.Chat.GetChatters;
13+
//
14+
// using TwitchUserConfig = Nullinside.Api.Model.Ddl.TwitchUserConfig;
15+
//
16+
// namespace Nullinside.Api.TwitchBot.Bots;
17+
//
18+
// /// <summary>
19+
// /// Searches for and bans known bots when they enter the chat.
20+
// /// </summary>
21+
// public class BanKnownBots : ABotRule {
22+
// /// <summary>
23+
// /// Handles refreshing the <see cref="KnownBotListUsername" /> collection.
24+
// /// </summary>
25+
// private static Task _ = Task.Run(async () => {
26+
// while (true) {
27+
// Task<ImmutableHashSet<string>?> twitchInsights = GetTwitchInsightsBots();
28+
// Task<ImmutableHashSet<string>?> commanderRoot = GetCommanderRootBots();
29+
// await Task.WhenAll(twitchInsights, commanderRoot);
30+
// if (null != twitchInsights.Result) {
31+
// KnownBotListUsername = twitchInsights.Result;
32+
// }
33+
//
34+
// if (null != commanderRoot.Result) {
35+
// KnownBotListUserId = commanderRoot.Result;
36+
// }
37+
//
38+
// // The list is enormous, force garbage collection.
39+
// GC.Collect();
40+
// GC.WaitForPendingFinalizers();
41+
// await Task.Delay(TimeSpan.FromMinutes(10));
42+
// }
43+
// });
44+
//
45+
// /// <summary>
46+
// /// The cache of known bots.
47+
// /// </summary>
48+
// public static ImmutableHashSet<string>? KnownBotListUsername { get; set; }
49+
//
50+
// /// <summary>
51+
// /// The cache of known bots.
52+
// /// </summary>
53+
// public static ImmutableHashSet<string>? KnownBotListUserId { get; set; }
54+
//
55+
// /// <summary>
56+
// /// Determine if the rule is enabled in the configuration.
57+
// /// </summary>
58+
// /// <param name="config">The user's configuration.</param>
59+
// /// <returns>True if it should run, false otherwise.</returns>
60+
// public override bool ShouldRun(TwitchUserConfig config) {
61+
// return config is { Enabled: true, BanKnownBots: true };
62+
// }
63+
//
64+
// /// <summary>
65+
// /// Searches for and bans known bots when they enter the chat.
66+
// /// </summary>
67+
// /// <param name="user">The user.</param>
68+
// /// <param name="config">The user's configuration.</param>
69+
// /// <param name="botProxy">The twitch api authenticated as the bot user.</param>
70+
// /// <param name="db">The database.</param>
71+
// /// <param name="stoppingToken">The cancellation token.</param>
72+
// public override async Task Handle(User user, TwitchUserConfig config, ITwitchApiProxy botProxy,
73+
// INullinsideContext db, CancellationToken stoppingToken = new()) {
74+
// if (null == user.TwitchId) {
75+
// return;
76+
// }
77+
//
78+
// // TODO: SKIP MODS AND VIPS
79+
//
80+
// // Get the list of people in the chat.
81+
// List<Chatter>? chatters =
82+
// (await botProxy.GetChannelUsers(user.TwitchId, Constants.BotId, stoppingToken))?.ToList();
83+
// if (null == chatters || chatters.Count == 0) {
84+
// return;
85+
// }
86+
//
87+
// // Perform the comparison in the lock to prevent multithreading issues.
88+
// // The collection is extremely large so we do not want to make a copy of it.
89+
// var botsInChatInsights = new List<Chatter>();
90+
// var botsInChatCommanderRoot = new List<Chatter>();
91+
// ImmutableHashSet<string>? knownBotUsernames = KnownBotListUsername;
92+
// ImmutableHashSet<string>? knownBotUserIds = KnownBotListUserId;
93+
//
94+
// if (null != knownBotUsernames) {
95+
// botsInChatInsights.AddRange(chatters.Where(k =>
96+
// knownBotUsernames.Contains(k.UserLogin.ToLowerInvariant())));
97+
// }
98+
//
99+
// if (null != knownBotUserIds) {
100+
// botsInChatCommanderRoot.AddRange(chatters.Where(k =>
101+
// knownBotUserIds.Contains(k.UserId.ToLowerInvariant())));
102+
// }
103+
//
104+
// // Remove the whitelisted bots
105+
// botsInChatInsights = botsInChatInsights
106+
// .Where(b => !Constants.WhitelistedBots.Contains(b.UserLogin.ToLowerInvariant())).ToList();
107+
// botsInChatCommanderRoot = botsInChatCommanderRoot
108+
// .Where(b => !Constants.WhitelistedBots.Contains(b.UserLogin.ToLowerInvariant())).ToList();
109+
//
110+
// // Ban them.
111+
// if (botsInChatInsights.Count != 0) {
112+
// await BanOnce(botProxy, db, user.TwitchId, botsInChatInsights.Select(b => (Id: b.UserId, Username: b.UserLogin)),
113+
// "[Bot] Username on Known Bot List", stoppingToken);
114+
// }
115+
//
116+
// if (botsInChatCommanderRoot.Count != 0) {
117+
// await BanOnce(botProxy, db, user.TwitchId,
118+
// botsInChatCommanderRoot.Select(b => (Id: b.UserId, Username: b.UserLogin)),
119+
// "[Bot] Username on Known Bot List", stoppingToken);
120+
// }
121+
// }
122+
//
123+
// /// <summary>
124+
// /// Gets the list of all known bots.
125+
// /// </summary>
126+
// /// <returns>The list of bots if successful, null otherwise.</returns>
127+
// private static async Task<ImmutableHashSet<string>?> GetTwitchInsightsBots() {
128+
// var stopwatch = new Stopwatch();
129+
// stopwatch.Start();
130+
// // Reach out to the api and find out what bots are online.
131+
// using var http = new HttpClient();
132+
// HttpResponseMessage response = await http.GetAsync("https://api.twitchinsights.net/v1/bots/all");
133+
// if (!response.IsSuccessStatusCode) {
134+
// return null;
135+
// }
136+
//
137+
// byte[]? content = await response.Content.ReadAsByteArrayAsync();
138+
// string? jsonString = Encoding.UTF8.GetString(content);
139+
// var liveBotsResponse = JsonConvert.DeserializeObject<TwitchInsightsLiveBotsResponse>(jsonString);
140+
// if (null == liveBotsResponse) {
141+
// return null;
142+
// }
143+
//
144+
// ImmutableHashSet<string> allBots = liveBotsResponse.bots
145+
// .Where(s => !string.IsNullOrWhiteSpace(s[0].ToString()))
146+
// #pragma warning disable 8602
147+
// .Select(s => s[0].ToString().ToLowerInvariant())
148+
// #pragma warning restore 8602
149+
// .ToImmutableHashSet();
150+
//
151+
// foreach (List<object>? list in liveBotsResponse.bots) {
152+
// list.Clear();
153+
// }
154+
//
155+
// liveBotsResponse.bots.Clear();
156+
// liveBotsResponse.bots = null;
157+
// liveBotsResponse = null;
158+
// content = null;
159+
// jsonString = null;
160+
// return allBots;
161+
// }
162+
//
163+
// /// <summary>
164+
// /// Gets the list of all known bots.
165+
// /// </summary>
166+
// /// <returns>The list of bots if successful, null otherwise.</returns>
167+
// private static async Task<ImmutableHashSet<string>?> GetCommanderRootBots() {
168+
// var stopwatch = new Stopwatch();
169+
// stopwatch.Start();
170+
// // Reach out to the api and find out what bots are online.
171+
// using var http = new HttpClient();
172+
// using HttpResponseMessage response =
173+
// await http.GetAsync("https://twitch-tools.rootonline.de/blocklist_manager.php?preset=known_bot_users");
174+
// if (!response.IsSuccessStatusCode) {
175+
// return null;
176+
// }
177+
//
178+
// byte[]? content = await response.Content.ReadAsByteArrayAsync();
179+
// string? jsonString = Encoding.UTF8.GetString(content);
180+
// var liveBotsResponse = JsonConvert.DeserializeObject<List<string>>(jsonString);
181+
// if (null == liveBotsResponse) {
182+
// return null;
183+
// }
184+
//
185+
// ImmutableHashSet<string> allBots = liveBotsResponse
186+
// #pragma warning disable 8602
187+
// .Select(s => s.ToLowerInvariant())
188+
// #pragma warning restore 8602
189+
// .ToImmutableHashSet();
190+
//
191+
// liveBotsResponse.Clear();
192+
// liveBotsResponse = null;
193+
// liveBotsResponse = null;
194+
// content = null;
195+
// jsonString = null;
196+
// return allBots;
197+
// }
198+
// }

0 commit comments

Comments
 (0)