-
Notifications
You must be signed in to change notification settings - Fork 1
/
Chatter.cs
281 lines (238 loc) · 8.62 KB
/
Chatter.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Serilog;
namespace AbevBot
{
public class Chatter
{
private const string CHATTERSFILE = ".chatters";
private const int STARTINGGAMBAPOINTS = 100;
private static bool UpdateRequired;
private static readonly Dictionary<long, Chatter> Chatters = new();
public static readonly List<string> AlwaysReadTTSFromThem = new();
public static readonly List<string> OverpoweredInFight = new();
public static readonly TimeSpan OfflineTimeout = TimeSpan.FromMinutes(30);
public long ID { get; set; }
public string Name { get; set; }
public DateTime LastTimeFollowed { get; set; } = DateTime.MinValue;
public int BackseatPoints { get; set; }
public int RudePoints { get; set; }
public GambaStats Gamba { get; set; }
public FightStats Fight { get; set; }
public DateTime LastWelcomeMessage { get; set; } = DateTime.MinValue;
public string WelcomeMessage { get; set; } = string.Empty;
[JsonIgnore]
public DateTime LastChatted { get; set; } = DateTime.MinValue;
public DateTime LastSongRequest { get; set; } = DateTime.MinValue;
/// <summary> Sets starting values for new chatter. </summary>
private void InitChatter(long id)
{
ID = id;
Gamba = new()
{
Points = STARTINGGAMBAPOINTS
};
}
public void AddGambaPoints(int points)
{
if (points > 0) { Gamba.Wins++; }
else if (points < 0) { Gamba.Looses++; }
else { Log.Warning("Gamba: {Name} gambler won {points} points. Something is not right Hmm.", Name, points); }
Gamba.Points += points;
if (Gamba.Points <= 0)
{
Gamba.Points = STARTINGGAMBAPOINTS;
Gamba.Bankruptcies++;
}
UpdateRequired = true;
}
public void AddBackseatPoint(int point)
{
BackseatPoints += point;
UpdateRequired = true;
}
public void AddRudePoint(int point)
{
RudePoints += point;
UpdateRequired = true;
}
public void AddFightExp(float exp)
{
Fight.CurrentExp += MathF.Round(exp, 2);
while (Fight.CurrentExp >= Fight.RequiredExp)
{
Fight.Level++;
Fight.CurrentExp -= Fight.RequiredExp;
Fight.CheckStats(Name, true);
}
Fight.CheckStats(Name);
UpdateRequired = true;
}
public void SetLastTimeFollowedToNow()
{
LastTimeFollowed = DateTime.Now;
UpdateRequired = true;
}
public void SetLastWelcomeMessageToNow()
{
LastWelcomeMessage = DateTime.Now.Date;
UpdateRequired = true;
}
public void SetWelcomeMessage(string msg)
{
WelcomeMessage = msg;
UpdateRequired = true;
}
public static Dictionary<long, Chatter> GetChatters()
{
if (Chatters is null || Chatters.Count == 0) LoadChattersFile();
return Chatters;
}
/// <summary> Returns a chatter or creates new one. </summary>
public static Chatter GetChatterByID(long userID, string userName)
{
if (Chatters is null || Chatters.Count == 0) LoadChattersFile();
Chatter c;
lock (Chatters)
{
if (!Chatters.TryGetValue(userID, out c))
{
c = new();
c.InitChatter(userID);
Chatters.Add(userID, c);
}
if (userName?.Length > 0) c.Name = userName.Trim(); // Update chatter name if provided
}
return c;
}
/// <summary> Returns a chatter or tries to create new one by acquiring all chatters and finding him. </summary>
public static Chatter GetChatterByName(string userName)
{
if (Chatters is null || Chatters.Count == 0) LoadChattersFile();
if (userName is null || userName.Length == 0)
{
Log.Warning("Get chatter by name provided empty user name!");
return null;
}
string name = userName.Trim().ToLower();
var chatter = Chatters.GetEnumerator();
while (chatter.MoveNext())
{
if (chatter.Current.Value.Name.ToLower().Equals(name)) return chatter.Current.Value;
}
var chatters = Chat.GetChatters();
foreach (var c in chatters)
{
if (c.name.ToLower().Equals(name))
{
Chatter cc = GetChatterByID(c.id, c.name);
cc.LastChatted = DateTime.Now;
return cc;
}
}
Log.Warning("Chatter {name} not found!", userName.Trim());
return null;
}
public static void UpdateChattersFile(bool forceUpdate = false)
{
if (!UpdateRequired && !forceUpdate) return;
UpdateRequired = false;
if (Chatters is null || Chatters.Count == 0) return;
Log.Information("Updating chatters file.");
string data;
lock (Chatters)
{
// Clean up chatters when force update is active - the bot is being closed
if (forceUpdate)
{
var chatter = Chatters.GetEnumerator();
while (chatter.MoveNext())
{
if (!CheckIfChatterIsActive(chatter.Current.Value)) Chatters.Remove(chatter.Current.Value.ID);
}
}
data = JsonSerializer.Serialize(Chatters, new JsonSerializerOptions() { WriteIndented = true });
}
try { File.WriteAllText(CHATTERSFILE, data); }
catch (Exception ex) { Log.Error("Error when updating chatters file: {ex}", ex); }
}
/// <summary> Loads chatters from chatters file. </summary>
public static void LoadChattersFile()
{
if (Chatters?.Count > 0) return;
FileInfo chattersFile = new(CHATTERSFILE);
if (chattersFile.Exists)
{
string data = File.ReadAllText(chattersFile.FullName);
if (data is null || data.Length == 0) { return; }
lock (Chatters)
{
var chat = JsonSerializer.Deserialize<Dictionary<long, Chatter>>(data);
foreach (var chatter in chat)
{
if (CheckIfChatterIsActive(chatter.Value)) Chatters.Add(chatter.Key, chatter.Value);
}
}
}
}
/// <summary> Checks several things to assess whether the chatter is active. </summary>
/// <param name="chatter">Chatter to be checked.</param>
/// <returns>true if chatter is active, otherwise false</returns>
private static bool CheckIfChatterIsActive(Chatter chatter)
{
if (chatter.Fight?.Level > 0) return true;
if (chatter.Gamba?.Wins != 0 || chatter.Gamba?.Looses != 0) return true;
if (chatter.RudePoints > 0) return true;
if (chatter.BackseatPoints > 0) return true;
if (chatter.WelcomeMessage?.Length > 0) return true;
// if (chatter.LastTimeFollowed != DateTime.MinValue) return true;
// All checks failed - the chatter is inactive and can be forgotten peepoSad
return false;
}
/// <summary><para> Looks through Chatters array to find every chatter that followed in less than 20 seconds. </para>
/// <para> Then bans find users for 10 hours, deletes them from Chatters array and deletes follow notifications. </para></summary>
public static void StopFollowBots()
{
if (Notifications.StopFollowBotsActive) { return; }
Notifications.StopFollowBotsActive = true;
Notifications.StopFollowBotsPause = true; // Pause notifications while follow notifications are being removed
Log.Warning("Stop follow bots clicked!");
TimeSpan followedLimit = TimeSpan.FromSeconds(60);
var now = DateTime.Now;
Notifications.ActivateShieldMode();
Chat.AddMessageToQueue("Stop follow bots activated FeelsGoodMan If you got banned and you are not a bot sorry pepeLost");
// Ban the chatters
LoadChattersFile();
Task.Run(() =>
{
// First clean up notifications because it's faster than sending http messages for bans
Notifications.CleanFollowNotifications();
Notifications.StopFollowBotsPause = false; // Unpause notifications from "stop follow bots active"
lock (Chatters)
{
var chatter = Chatters.GetEnumerator();
while (chatter.MoveNext())
{
if (now - chatter.Current.Value.LastTimeFollowed <= followedLimit)
{
// Followed in last x seconds - BAN!
Chat.BanChatter("follow bot? If not just issue unban request :)", chatter.Current.Value, 0); // perma
Chatters.Remove(chatter.Current.Value.ID);
}
}
}
Notifications.StopFollowBotsActive = false;
});
}
public override string ToString() { return Name; }
}
public class SkipSongChatter
{
public long ChatterID { get; set; }
public DateTime TimeRequested { get; set; }
}
}