-
Notifications
You must be signed in to change notification settings - Fork 1
/
DiscordStatus.cs
193 lines (169 loc) · 6.65 KB
/
DiscordStatus.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
// VERSION 1.3
// MADE BY @SENTENNIAL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BattleBitAPI.Common;
using BBRAPIModules;
using Discord;
using Discord.Rest;
using Discord.WebSocket;
namespace BattleBitAPI.Features
{
[RequireModule(typeof(PlaceholderLib))]
[Module("Connects each server to a Discord Bot, and updates the Discord Bot's status with the server's player-count and map information.", "1.3")]
public class DiscordStatus : BattleBitModule
{
public DiscordConfiguration Configuration { get; set; }
private List<string> MessageQueue = new();
private DiscordSocketClient discordClient;
private ITextChannel chatMessageChannel;
private ITextChannel reportsChannel;
private bool discordReady = false;
public override Task OnConnected()
{
if (string.IsNullOrEmpty(Configuration.DiscordBotToken))
{
Unload();
throw new Exception("API Key is not set. Please set it in the configuration file.");
}
Task.Run(() => connectDiscord()).ContinueWith(t => Console.WriteLine($"Error during Discord connection {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted);
Task.Run(UpdateTimer).ContinueWith(t => Console.WriteLine($"Error during Discord Status update {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted);
Task.Run(SendChatMessages).ContinueWith(t => Console.WriteLine($"Error sending chat messages {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted);
return Task.CompletedTask;
}
private async void UpdateTimer()
{
while (this.IsLoaded && this.Server.IsConnected)
{
if (discordReady)
await updateDiscordStatus(getStatus());
await Task.Delay(10000);
}
}
private async void SendChatMessages()
{
while (this.IsLoaded && this.Server.IsConnected)
{
if (!discordReady)
{
await Task.Delay(2000);
continue;
}
if (chatMessageChannel == null)
{
Logger.Warn("!! CHAT MESSAGE CHANNEL ID IS INVALID !!");
break;
}
if (MessageQueue.Count == 0)
{
continue;
}
List<string> messages = MessageQueue.Take(10).ToList();
MessageQueue.RemoveRange(0, messages.Count);
await chatMessageChannel.SendMessageAsync(string.Join(Environment.NewLine, messages));
await Task.Delay(10000);
}
}
public override void OnModuleUnloading()
{
Task.Run(() => disconnectDiscord());
}
public override Task OnPlayerReported(RunnerPlayer from, RunnerPlayer to, ReportReason reason, string additional)
{
if (!discordReady)
return Task.CompletedTask;
if (reportsChannel == null)
reportsChannel = chatMessageChannel;
Task.Run(() => SendReport(from, to, reason, additional));
return Task.CompletedTask;
}
private async Task SendReport(RunnerPlayer from, RunnerPlayer to, ReportReason reason, string additional)
{
string additionalInfo = additional != string.Empty ? $"\nAdditional Info: {additional}" : string.Empty;
await reportsChannel.SendMessageAsync($":smiling_imp: ``{from}`` reported ``{to}`` for {reason}!{additionalInfo}");
}
public override async Task<bool> OnPlayerTypedMessage(RunnerPlayer player, ChatChannel channel, string msg)
{
string chatMessage = new PlaceholderLib(":speech_balloon: ``{name}`` ({channel}): ``{message}``")
.AddParam("name", player.Name)
.AddParam("channel", ToStringChatChannel(channel))
.AddParam("message", msg)
.Run();
MessageQueue.Add(chatMessage);
return true;
}
private async Task connectDiscord()
{
var config = new DiscordSocketConfig
{
GatewayIntents = GatewayIntents.AllUnprivileged
};
discordClient = new DiscordSocketClient(config);
discordClient.Ready += ReadyAsync;
await discordClient.LoginAsync(TokenType.Bot, Configuration.DiscordBotToken);
await discordClient.StartAsync();
chatMessageChannel = await discordClient.GetChannelAsync(Configuration.ChatChannelId) as ITextChannel;
ulong reportsId = Configuration.ReportChannelId != 0 ? Configuration.ReportChannelId : Configuration.ChatChannelId;
reportsChannel = await discordClient.GetChannelAsync(reportsId) as ITextChannel;
}
private string getStatus()
{
return "" + Server.CurrentPlayerCount + "/" + Server.MaxPlayerCount +
"(" + Server.InQueuePlayerCount + ") on " + Server.Map + " " + Server.Gamemode;
}
private async Task disconnectDiscord()
{
discordReady = false;
try
{
await discordClient.StopAsync();
}
catch (Exception)
{
}
}
private Task ReadyAsync()
{
discordReady = true;
Task.Run(() => updateDiscordStatus(getStatus()));
return Task.CompletedTask;
}
private async Task updateDiscordStatus(string status)
{
if (discordReady == false)
{
return;
}
try
{
await discordClient.SetGameAsync(status);
}
catch (Exception)
{
}
}
private string ToStringChatChannel(ChatChannel channel)
{
switch (channel)
{
case ChatChannel.AllChat:
return "All Chat";
case ChatChannel.TeamChat:
return "Team Chat";
case ChatChannel.SquadChat:
return "Squad Chat";
default:
return "All Chat";
}
}
}
public class DiscordConfiguration : ModuleConfiguration
{
public string DiscordBotToken { get; set; } = string.Empty;
public int MaxMessageCount { get; set; } = 10;
public ulong ChatChannelId { get; set; } = 0;
public ulong ReportChannelId { get; set; } = 0;
}
}