private async Task <PairInSecretRoom> MoveToPrivateLobbyAsync(UsersPairMatch pair) { //DebugLogWriteLine($"Moving {pair.A} and {pair.B} to room... "); UsersInLobbies.Remove(pair.A.User); UsersInLobbies.Remove(pair.B.User); var privateRoom = await Guild.CreateChannelAsync($"Secret Room {Guid.NewGuid().ToString()}", ChannelType.Voice, DateSecretCategory , overwrites : new DiscordOverwriteBuilder[] { SecretRoomOverwriteBuilder }); SecretRooms.Add(privateRoom); DebugLogWrite("room created... "); var timeout = DateTime.Now.AddMilliseconds(SecretRoomTime); pair.A.State.EnteredPrivateRoomTime = pair.B.State.EnteredPrivateRoomTime = timeout; var p = new PairInSecretRoom() { Users = new List <DiscordMember>() { pair.A.User, pair.B.User }, SecretRoom = privateRoom, Timeout = timeout }; PairsInSecretRooms.Add(p); DebugLogWrite("moving... "); _ = privateRoom.PlaceMemberAsync(pair.A.User).ConfigureAwait(false); _ = privateRoom.PlaceMemberAsync(pair.B.User).ConfigureAwait(false); pair.A.State.AddMatch(pair.B.User.Id); pair.B.State.AddMatch(pair.A.User.Id); DebugLogWrite("finished"); return(p); }
//public void ApplyGenderAndOptionReactions(DiscordUser user, DiscordEmoji emoji) { // AllUserStates.TryGetValue(user.Id, out var uState); // if (uState == null) { // uState = new UserState() { UserId = user.Id }; // AllUserStates.Add(user.Id, uState); // } // if (emoji == MaleEmoji) { // uState.Gender = GenderEnum.Male; // WelcomeMessage.DeleteReactionAsync(MaleEmoji, user); // uState.AgeOptions = 0; // } else if (emoji == FemaleEmoji) { // uState.Gender = GenderEnum.Female; // WelcomeMessage.DeleteReactionAsync(FemaleEmoji, user); // uState.AgeOptions = 0; // } else { // var option = OptionEmojis.IndexOf(emoji); // uState.AgeOptions ^= option; //toggle age group // } //} /// <summary> /// Checks lobbies, cleans them, refreshes users, checks secret rooms updates timeouts, cleans them /// TODO change secret room behaviour /// </summary> /// <returns></returns> async Task VoiceChannelsInitAsync() { //Clean lobbies await CombLobbies().ConfigureAwait(false); //check users in lobbies RefreshUsersInLobbies(); //check secret rooms PairsInSecretRooms.Clear(); foreach (var r in SecretRooms.ToArray()) { if (r.Users.Count() > 1) { var uState = AddOrGetUserState(r.Users.First()); var pair = new PairInSecretRoom() { SecretRoom = r, Users = r.Users.ToList() }; //Try get timeout if (uState != null && uState.EnteredPrivateRoomTime.HasValue) { pair.Timeout = uState.EnteredPrivateRoomTime.Value.AddMilliseconds(SecretRoomTime); } else { pair.Timeout = DateTime.Now; } PairsInSecretRooms.Add(pair); _ = TimeoutDisband(pair) .ConfigureAwait(false); } else { SecretRooms.Remove(r); try { await r.DeleteAsync().ConfigureAwait(false); } catch (Exception) { } } } }
/// <summary> /// User changed state in voice lobbies (joined/left) /// </summary> /// <param name="e"></param> /// <returns></returns> public async Task VoiceStateUpdated(VoiceStateUpdateEventArgs e) { InitTask?.Wait(); //DebugLogWriteLine("VoiceStateUpdated: "); if (e.After?.Channel != e.Before?.Channel) //Channel changed { var beforeInLobbies = DateVoiceLobbies.Contains(e.Before?.Channel); var afterInLobbies = DateVoiceLobbies.Contains(e.After?.Channel); var beforeInSecretRooms = SecretRooms.Contains(e.Before?.Channel); var afterInSecretRooms = SecretRooms.Contains(e.After?.Channel); if (!beforeInLobbies && !beforeInSecretRooms && afterInLobbies) { //User connected to lobbies DebugLogWriteLine($"User {e.User} connected to {e.Channel} "); UserConnected_AddToActivity(e.User); //Start matching session TryStartMatchingTask(); } else if ((beforeInLobbies || beforeInSecretRooms) && !afterInLobbies && !afterInSecretRooms) { //User left activity DebugLogWriteLine($"User {e.User} left activity "); if (beforeInLobbies) { UsersInLobbies.Remove(e.User); RemoveStateFor(e.User); } //remove disband secret room if one left TODO check logic if (beforeInSecretRooms) { RemoveStateFor(e.User); //DebugLogWrite($"trying to disbnad {e.Before.Channel}... "); await disbandRemoveSecretRoom(e.Before.Channel).ConfigureAwait(false); //DebugLogWrite($"{e.Before.Channel} removed/disbanded"); } } else if (beforeInLobbies && afterInLobbies) { DebugLogWriteLine($"User {e.User} switched lobbies "); //User switched Lobbies } else if (beforeInLobbies && afterInSecretRooms) { DebugLogWriteLine($"User {e.User} moved to {e.After.Channel} "); //Moved to secret room UsersInLobbies.Remove(e.User); } else if (beforeInSecretRooms && afterInLobbies) { //Returned from secret room RemoveStateFor(e.User); DebugLogWriteLine($"User {e.User} returned to lobby, trying to disbnad {e.Before.Channel}... "); UserConnected_AddToActivity(e.User); await disbandRemoveSecretRoom(e.Before.Channel).ConfigureAwait(false); //DebugLogWrite($"{e.Before.Channel} removed/disbanded. Starting MatchingTask"); //Start matching session TryStartMatchingTask(); } TryCombLobbies(); } async Task disbandRemoveSecretRoom(DiscordChannel channel) { //Remove empty room, if 1 user left, move him into lobby 0, later room will be removed if (channel.Users.Count() == 0) { try { //usually shouldn't throw, but in debug await channel.DeleteAsync().ConfigureAwait(false); } catch { //DebugLogWrite($"Exception while deleting "); } } else if (channel.Users.Count() == 1) { try { var moveMember = await Guild.GetMemberAsync(channel.Users.First().Id); await DateVoiceLobbies[0].PlaceMemberAsync(moveMember); } catch { //DebugLogWrite($"Exception while moving member "); } } } }
/// <summary> /// Gets all channels, members in them and set's up event handlers /// </summary> /// <param name="guild"></param> /// <returns></returns> internal async Task Initialize(DiscordGuild guild) { //DebugLogWriteLine($"Initiating {guild} GuildTask... "); //Init guild Guild = guild; GuildId = guild.Id; SecretRoomOverwriteBuilder = new DiscordOverwriteBuilder(); SecretRoomOverwriteBuilder.For(Guild.EveryoneRole); SecretRoomOverwriteBuilder.Deny(Permissions.AccessChannels); //PersonalChannelOverwriteBuilder = new DiscordOverwriteBuilder(); //PersonalChannelOverwriteBuilder.Allow(Permissions.AccessChannels); LogChannel = guild.GetChannel(LogChannelId); if (LogChannel != null) { LogMessage = await LogChannel.SendMessageAsync($"Begin of log {DateTime.Now.ToString()}\n"); } //Init RootCategory Guild.Channels.TryGetValue(DateCategoryId, out DiscordChannel cat); if (cat == null) { string m = $"Initialize failed. No Category found on + {DateCategoryId}"; //DebugLogWriteLine(m); throw new Exception(m); } DateRootCategory = cat; Guild.Channels.TryGetValue(DateSecretCategoryId, out DiscordChannel secCat); DateSecretCategory = secCat; //DebugLogWrite("Initiating voice channels... "); //VoiceChannels DateVoiceLobbies.Clear(); SecretRooms.Clear(); DateVoiceLobbies.AddRange(GetVoiceLobbies()); SecretRooms.AddRange(GetSecretRooms()); await VoiceChannelsInitAsync().ConfigureAwait(false); if (DateVoiceLobbies.Count == 0 || DateVoiceLobbies.All(c => c.Users.Count() > 0)) { await AddLastEmptyVoiceLobby().ConfigureAwait(false); } //DebugLogWrite("Initiating Emojis... "); //GetEmojis MaleEmoji = DiscordEmoji.FromUnicode(DateBot.Instance.Client, MaleEmojiId); FemaleEmoji = DiscordEmoji.FromUnicode(DateBot.Instance.Client, FemaleEmojiId); OptionEmojis.Clear(); OptionEmojis.AddRange(OptionEmojiIds.Select(id => DiscordEmoji.FromUnicode(DateBot.Instance.Client, id))); LikeEmoji = DiscordEmoji.FromUnicode(DateBot.Instance.Client, LikeEmojiId); DisLikeEmoji = DiscordEmoji.FromUnicode(DateBot.Instance.Client, DisLikeEmojiId); TimeEmoji = DiscordEmoji.FromUnicode(DateBot.Instance.Client, TimeEmojiId); CancelLikeEmoji = DiscordEmoji.FromUnicode(DateBot.Instance.Client, CancelLikeEmojiId); //DebugLogWrite("Initiating Users in lobbies... "); //Check and add users in lobbies foreach (var u in UsersInLobbies.ToArray()) { AddOrGetUserState(u).LastEnteredLobbyTime = DateTime.Now; } //DebugLogWrite("Initiating Welcome message... "); //Check for welcome message TODO add option emojis DateTextChannel = Guild.GetChannel(DateTextChannelId); await WelcomeMessageInit().ConfigureAwait(false); _ = PrivateControlsMessageInit().ConfigureAwait(false); //UpdateTimer = new Timer(TimeSpan.FromSeconds(30).TotalMilliseconds) { AutoReset = true }; //UpdateTimer.Elapsed += UpdateTimer_Elapsed; //UpdateTimer.Start(); //DebugLogWrite("finished"); InitTask = null; Initialized = true; if (UsersInLobbies.Count > 0) { TryStartMatchingTask(); } }