using System.Collections.ObjectModel; using System.Text; using Discord; using Discord.WebSocket; using Newtonsoft.Json; namespace Boyfriend; public static class Boyfriend { public static readonly StringBuilder StringBuilder = new(); private static readonly Dictionary GuildCache = new(); private static readonly DiscordSocketConfig Config = new() { MessageCacheSize = 250, GatewayIntents = GatewayIntents.All, AlwaysDownloadUsers = true, AlwaysResolveStickers = false, AlwaysDownloadDefaultStickers = false, LargeThreshold = 500 }; private static readonly List> ActivityList = new() { Tuple.Create(new Game("C418 - Mall", ActivityType.Listening), new TimeSpan(0, 3, 18)), Tuple.Create(new Game("C418 - Thirteen", ActivityType.Listening), new TimeSpan(0, 2, 57)), Tuple.Create(new Game("Spotify Ads", ActivityType.Listening), new TimeSpan(0, 0, 15)) }; public static readonly DiscordSocketClient Client = new(Config); private static readonly Dictionary> GuildConfigDictionary = new(); private static readonly Dictionary>> RemovedRolesDictionary = new(); public static readonly Dictionary DefaultConfig = new() { { "Lang", "en" }, { "Prefix", "!" }, { "RemoveRolesOnMute", "false" }, { "SendWelcomeMessages", "true" }, { "ReceiveStartupMessages", "false" }, { "FrowningFace", "true" }, { "WelcomeMessage", Messages.DefaultWelcomeMessage }, { "EventStartedReceivers", "interested,role" }, { "StarterRole", "0" }, { "MuteRole", "0" }, { "EventNotifyReceiverRole", "0" }, { "AdminLogChannel", "0" }, { "BotLogChannel", "0" }, { "EventCreatedChannel", "0" }, { "EventStartedChannel", "0" }, { "EventCancelledChannel", "0" }, { "EventCompletedChannel", "0" }, { "EventEarlyNotificationOffset", "0" } }; public static void Main() { Init().GetAwaiter().GetResult(); } private static async Task Init() { var token = (await File.ReadAllTextAsync("token.txt")).Trim(); Client.Log += Log; await Client.LoginAsync(TokenType.Bot, token); await Client.StartAsync(); EventHandler.InitEvents(); while (true) { foreach (var activity in ActivityList) { await Client.SetActivityAsync(activity.Item1); await Task.Delay(activity.Item2); } } // ReSharper disable once FunctionNeverReturns } private static Task Log(LogMessage msg) { Console.WriteLine(msg.ToString()); return Task.CompletedTask; } public static async Task WriteGuildConfigAsync(ulong id) { var json = JsonConvert.SerializeObject(GuildConfigDictionary[id], Formatting.Indented); var removedRoles = JsonConvert.SerializeObject(RemovedRolesDictionary[id], Formatting.Indented); await File.WriteAllTextAsync($"config_{id}.json", json); await File.WriteAllTextAsync($"removedroles_{id}.json", removedRoles); } public static Dictionary GetGuildConfig(ulong id) { if (!RemovedRolesDictionary.ContainsKey(id)) RemovedRolesDictionary.Add(id, new Dictionary>()); if (GuildConfigDictionary.TryGetValue(id, out var cfg)) return cfg; var path = $"config_{id}.json"; if (!File.Exists(path)) File.Create(path).Dispose(); var json = File.ReadAllText(path); var config = JsonConvert.DeserializeObject>(json) ?? new Dictionary(); if (config.Keys.Count < DefaultConfig.Keys.Count) { // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator // Avoids a closure allocation with the config variable foreach (var key in DefaultConfig.Keys) if (!config.ContainsKey(key)) config.Add(key, DefaultConfig[key]); } else if (config.Keys.Count > DefaultConfig.Keys.Count) { foreach (var key in config.Keys.Where(key => !DefaultConfig.ContainsKey(key))) config.Remove(key); } GuildConfigDictionary.Add(id, config); return config; } public static Dictionary> GetRemovedRoles(ulong id) { if (RemovedRolesDictionary.TryGetValue(id, out var dict)) return dict; var path = $"removedroles_{id}.json"; if (!File.Exists(path)) File.Create(path); var json = File.ReadAllText(path); var removedRoles = JsonConvert.DeserializeObject>>(json) ?? new Dictionary>(); RemovedRolesDictionary.Add(id, removedRoles); return removedRoles; } public static SocketGuild FindGuild(ulong channel) { if (GuildCache.TryGetValue(channel, out var gld)) return gld; foreach (var guild in Client.Guilds) { // ReSharper disable once LoopCanBeConvertedToQuery foreach (var x in guild.Channels) if (x.Id == channel) { GuildCache.Add(channel, guild); return guild; } } throw new Exception("Could not find guild by channel!"); } }