· 4 years ago · Jul 21, 2021, 10:12 PM
1// Reference: discord-webhook-client
2// Reference: notifique-me
3using ConVar;
4using Newtonsoft.Json;
5using Oxide.Core;
6using Oxide.Core.Libraries.Covalence;
7using Oxide.Core.Plugins;
8using System;
9using System.Collections.Generic;
10using System.Linq;
11using WebSocketSharp;
12using JNogueira.Discord.Webhook.Client;
13using System.Text;
14namespace Oxide.Plugins
15{
16 [Info("Auto Demo Record Lite", "Pho3niX90", "1.0.82")]
17 [Description("Automatic recording based on conditions.")]
18 internal class AutoDemoRecordLite : RustPlugin
19 {
20 private List<ARReport> _reports = new List<ARReport>();
21 private Dictionary<ulong, Timer> _timers = new Dictionary<ulong, Timer>();
22 private ARConfig config;
23 int lastSavedCount = 0;
24 public string date ="";
25 [PluginReference]
26 Plugin DiscordApi, DiscordMessages;
27
28 private void Loaded() {
29 LoadData();
30 }
31
32 private void Unload() {
33 SaveData();
34
35 _reports.Clear();
36 _reports = null;
37
38 foreach (var player in BasePlayer.activePlayerList) {
39 if (player.Connection.IsRecording)
40 player.Connection.StopRecording();
41 }
42
43 foreach (Timer timer in _timers.Values) {
44 timer.Destroy();
45 }
46
47 _timers.Clear();
48 _timers = null;
49 }
50
51 protected override void LoadDefaultMessages() {
52 lang.RegisterMessages(new Dictionary<string, string> {
53 ["Recording Started"] = "Recording started for player {0}, eta is {1} mins",
54 ["Recording Ended"] = "Recording finished for player {0}, player was recorded for {1} mins",
55 }, this);
56 }
57
58 string GetMsg(string key) => lang.GetMessage(key, this);
59
60 void OnPlayerReported(BasePlayer reporter, string targetName, string targetId, string subject, string message, string type) {
61 ulong targetIdLong = 0;
62 if (ulong.TryParse(targetId, out targetIdLong)) {
63 var report = new ARReport(reporter.UserIDString, reporter.displayName, targetId, targetName, subject, message, type);
64 _reports.Add(report);
65 ProcessF7(targetIdLong, report);
66 }
67 }
68
69 void OnPlayerCommand(BasePlayer player, string command, string[] args) {
70 if (!command.ToLower().Equals("report") || args.Length < 2) return;
71
72 var target = BasePlayer.Find(args[0]);
73 if (target == null) return;
74
75 List<string> reason = args.Skip(1).ToList();
76
77 var report = new ARReport(player.UserIDString, player.displayName, target.UserIDString, target.displayName, "Report", string.Join(" ", reason), "Report");
78 _reports.Add(report);
79 ProcessF7(target.userID, report);
80 }
81
82 void ReportCommand(IPlayer reporter, IPlayer target, string reason) {
83 var report = new ARReport(reporter.Id, reporter.Name, target.Id, target.Name, "DM Report", reason, "DM Report");
84 _reports.Add(report);
85 ProcessF7(ulong.Parse(target.Id), report);
86 }
87
88 private void OnDestroy() {
89 foreach (Timer timer in _timers.Values) {
90 timer.Destroy();
91 }
92 _timers.Clear();
93 _reports.Clear();
94 }
95
96 void ProcessF7(ulong targetId, ARReport report = null) {
97 BasePlayer accused = BasePlayer.FindByID(targetId);
98 if (accused == null) return;
99 if (accused.IsConnected) {
100 // record player only if he has reaced the amount in the config. And only when there is no recording active.
101 if (CheckReports(accused) >= config.AR_Report) {
102 if (!_timers.ContainsKey(accused.userID)) {
103 StartRecording(accused, report);
104 }
105 }
106 }
107 }
108
109 void StartRecording(BasePlayer player, ARReport report = null) {
110 var msg = string.Format(GetMsg("Recording Started"), player.UserIDString, config.AR_Report_Length);
111 Puts(msg);
112
113 if (config.AR_Discord_Notify_RecordStart) NotifyDiscord(player, msg, report, true);
114 date = DateTime.Now.ToString();
115 player.StartDemoRecording();
116 if (config.AR_Report_Length > 0) {
117 _timers[player.userID] = timer.Once(config.AR_Report_Length * 10, () => StopRecording(player, report));
118 }
119 }
120
121 void StopRecording(BasePlayer player, ARReport report) {
122 var msg = string.Format(GetMsg("Recording Ended"), player.UserIDString, config.AR_Report_Length);
123 Puts(msg);
124 if (config.AR_Discord_Notify_RecordStop) NotifyDiscord(player, msg, report, false);
125 if (_timers.ContainsKey(player.userID)) {
126 player.StopDemoRecording();
127 if (config.AR_Clear_Counter) {
128 _reports.RemoveAll(x => x.targetId == player.UserIDString);
129 }
130 _timers.Remove(player.userID);
131 }
132 }
133
134 int CheckReports(BasePlayer player) => config.AR_Report_Seconds > 0
135 ? this._reports.Count(x => secondsAgo(x.created) <= config.AR_Report_Seconds && x.targetId == player.UserIDString)
136 : this._reports.Count(x => x.targetId == player.UserIDString);
137
138
139 int secondsAgo(DateTime timeFrom) => (int)Math.Round((DateTime.UtcNow - timeFrom).TotalSeconds);
140
141
142 void NotifyDiscord(BasePlayer player, string msg, ARReport report, bool isStart) {
143 if (!config.AR_Discord_Webhook.IsNullOrEmpty() && !config.Equals("https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks")
144 && (config.AR_Discord_Notify_RecordStart || config.AR_Discord_Notify_RecordStop)) {
145 List<EmbedFieldList> fields = new List<EmbedFieldList>();
146
147 fields.Add(new EmbedFieldList() {
148 name = covalence.Server.Name,
149 value = $"[steam://connect/{covalence.Server.Address}:{covalence.Server.Port}](steam://connect/{covalence.Server.Address}:{covalence.Server.Port})",
150 inline = true
151 });
152
153 if (report != null &&
154 ((isStart && config.AR_Discord_Notify_RecordStartMsg) || (!isStart && config.AR_Discord_Notify_RecordStopMsg))) {
155 fields.Add(new EmbedFieldList() {
156 name = "Reporter",
157 value = $"{report.reporterName} ({report.reporterId})",
158 inline = false
159 });
160 fields.Add(new EmbedFieldList() {
161 name = "Report Subject",
162 value = $"{report.type}: {report.subject}",
163 inline = false
164 });
165 fields.Add(new EmbedFieldList() {
166 name = "Report Message",
167 value = report.message,
168 inline = false
169 });
170 }
171 /* string Filepah = $"oxide//data//{player.UserIDString}//{DateTime.Now}.dem";
172 byte[] readText = File.ReadAllBytes(Filepah);;*/
173
174 fields.Add(new EmbedFieldList() {
175 name = player.displayName,
176 value = msg,
177 inline = false
178
179 });
180 if (!isStart)
181 {
182 PrintWarning("1");
183 PrintWarning("2");
184 var client = new DiscordWebhookClient("https://discordapp.com/api/webhooks/867432844162891828/kiamC_M2wvtL_9gvUxQUdrnvNrlfpGHRWylvz47c1HQl7i-7WA1ksJ0jh27RPo2UF25t");
185
186// Create your DiscordMessage with all parameters of your message.
187 var message = new DiscordMessage(
188 "Discord Webhook Client sent this message! " + DiscordEmoji.Grinning,
189 username: "Username",
190 avatarUrl: "https://avatars3.githubusercontent.com/u/24236993?s=460&v=4",
191 tts: false,
192 embeds: new[]
193 {
194 new DiscordMessageEmbed(
195 "Embed title " + DiscordEmoji.Thumbsup,
196 color: 0,
197 author: new DiscordMessageEmbedAuthor("Embed 1 author name"),
198 url: "https://github.com/jlnpinheiro/discord-webhook-client/",
199 description: "This is a embed description.",
200 fields: new[]
201 {
202 new DiscordMessageEmbedField("Field 1 name", "Field 1 value"),
203 new DiscordMessageEmbedField("Field 2 name", "Field 2 value")
204 },
205 thumbnail: new DiscordMessageEmbedThumbnail("https://avatars3.githubusercontent.com/u/24236993?s=460&v=4"),
206 image: new DiscordMessageEmbedImage("https://avatars3.githubusercontent.com/u/24236993?s=460&v=4"),
207 footer: new DiscordMessageEmbedFooter("This is a embed footer text", "https://avatars3.githubusercontent.com/u/24236993?s=460&v=4")
208 )
209 }
210);
211
212var file1 = new DiscordFile($"{player.displayName}/{date}", Encoding.UTF8.GetBytes($"oxide//data//{player.UserIDString}//{date}.dem"));
213
214
215// Send the message!
216 client.SendToDiscord(message, new[] { file1 });
217
218 }
219 string json = JsonConvert.SerializeObject(fields.ToArray());
220
221 if (DiscordApi != null && DiscordApi.IsLoaded) {
222 DiscordApi?.Call("API_SendEmbeddedMessage", config.AR_Discord_Webhook, "Auto Demo Recorder", config.AR_Discord_Color, json);
223 } else if (DiscordMessages != null && DiscordMessages.IsLoaded) {
224 DiscordMessages?.Call("API_SendFancyMessage", config.AR_Discord_Webhook, "Auto Demo Recorder", config.AR_Discord_Color, json);
225 }
226 else {
227 Puts("No discord API plugin loaded, will not publish to hook!");
228 }
229 }
230 }
231 public void DiscordAPI(string date ,string playername) {
232 PrintWarning("2");
233 var client = new DiscordWebhookClient("https://discordapp.com/api/webhooks/867432844162891828/kiamC_M2wvtL_9gvUxQUdrnvNrlfpGHRWylvz47c1HQl7i-7WA1ksJ0jh27RPo2UF25t");
234
235// Create your DiscordMessage with all parameters of your message.
236 var message = new DiscordMessage(
237 "rerer"
238);
239var file1 = new DiscordFile($"{playername}/{date}", Encoding.UTF8.GetBytes($"oxide//data//{playername}//{date}.dem"));
240
241
242// Send the message!
243 client.SendToDiscord(message, new[] { file1 });
244
245 }
246
247
248
249 #region Configuration
250 private class ARConfig
251 {
252 // Config default vars
253 public int AR_Report = 1;
254 public int AR_Report_Length = 1;
255 public bool AR_Clear_Counter = false;
256 public string AR_Discord_Webhook = "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
257 public int AR_Discord_Color = 39423;
258 public bool AR_Discord_Notify_RecordStart = false;
259 public bool AR_Discord_Notify_RecordStop = false;
260 public int AR_Report_Seconds = 0;
261 public bool AR_Discord_Notify_RecordStartMsg = true;
262 public bool AR_Discord_Notify_RecordStopMsg = false;
263 public bool AR_Save_Reports = true;
264
265 // Plugin reference
266 private AutoDemoRecordLite plugin;
267 public ARConfig(AutoDemoRecordLite plugin) {
268 this.plugin = plugin;
269 /**
270 * Load all saved config values
271 * */
272 GetConfig(ref AR_Report, "Auto record after X reports");
273 GetConfig(ref AR_Report_Length, "Auto record for X minutes");
274 GetConfig(ref AR_Clear_Counter, "Clear report counter after recording?");
275 GetConfig(ref AR_Discord_Webhook, "Discord Webhook");
276 GetConfig(ref AR_Discord_Color, "Discord MSG Color");
277 GetConfig(ref AR_Discord_Notify_RecordStart, "Discord: Notify if recording is started");
278 GetConfig(ref AR_Discord_Notify_RecordStartMsg, "Discord: Include report with start message?");
279 GetConfig(ref AR_Discord_Notify_RecordStop, "Discord: Notify if recording is stopped");
280 GetConfig(ref AR_Discord_Notify_RecordStopMsg, "Discord: Include report with end message?");
281 GetConfig(ref AR_Report_Seconds, "Only record when reports within X seconds");
282 GetConfig(ref AR_Save_Reports, "Save/Load reports to datafile on reload");
283
284 plugin.SaveConfig();
285 }
286
287 private void GetConfig<T>(ref T variable, params string[] path) {
288 if (path.Length == 0) return;
289 if (plugin.Config.Get(path) == null) {
290 SetConfig(ref variable, path);
291 plugin.PrintWarning($"Added new field to config: {string.Join("/", path)}");
292 }
293 variable = (T)Convert.ChangeType(plugin.Config.Get(path), typeof(T));
294 }
295
296 private void SetConfig<T>(ref T variable, params string[] path) => plugin.Config.Set(path.Concat(new object[] { variable }).ToArray());
297
298 }
299 protected override void LoadConfig() {
300 base.LoadConfig();
301 config = new ARConfig(this);
302 }
303
304 void LoadData() {
305 if (!config.AR_Save_Reports) return;
306 try {
307 _reports = Interface.Oxide.DataFileSystem.ReadObject<List<ARReport>>(this.Name);
308 lastSavedCount = _reports.Count();
309 } catch (Exception e) {
310 Puts(e.Message);
311 }
312 }
313
314 void SaveData() {
315 int recordsDiff = _reports.Count() - lastSavedCount;
316 if (!config.AR_Save_Reports || recordsDiff == 0) return;
317 try {
318 Interface.Oxide.DataFileSystem.WriteObject(this.Name, _reports, true);
319 } catch (Exception e) {
320 Puts(e.Message);
321 }
322 }
323
324 protected override void LoadDefaultConfig() => PrintWarning("Generating new configuration file.");
325 #endregion
326
327 #region Classes
328 public class EmbedFieldList
329 {
330 public string name { get; set; }
331 public string value { get; set; }
332 public bool inline { get; set; }
333 }
334
335 public class ARReport
336 {
337 public string reporterName;
338 public string reporterId;
339 public string targetName;
340 public string targetId;
341 public string subject;
342 public string message;
343 public string type;
344 public DateTime created;
345 public ARReport() { }
346 public ARReport(string reporterId, string reporterName, string targetId, string targetName, string subject, string message, string type) {
347 this.reporterId = reporterId;
348 this.reporterName = reporterName;
349 this.targetId = targetId;
350 this.targetName = targetName;
351 this.subject = subject;
352 this.message = message;
353 this.type = type;
354 this.created = DateTime.UtcNow;
355 }
356 public ARReport(string targetId, string targetName) {
357 this.targetName = targetName;
358 this.targetId = targetId;
359 }
360 }
361 #endregion
362 }
363}