Beispiel #1
0
        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);
        }
Beispiel #2
0
        private void TryMatchUsers()
        {
            if (UsersInLobbies.Count > 1)
            {
                var userStatePairsInLobbies = UsersInLobbies.Join(AllUserStates,
                                                                  u => u.Id, s => s.Key,
                                                                  (u, s) => new UserStateDiscordUserPair {
                    User  = Guild.GetMemberAsync(s.Key).Result,
                    State = s.Value
                }).ToArray();
                var r       = new Random(DateTime.Now.Millisecond);
                var matches = (from a in userStatePairsInLobbies.OrderBy(u => r.Next())
                               from b in userStatePairsInLobbies
                               select Match(a.State, b.State))
                              .Where(m => m.A.State != m.B.State && m.A.State.Gender != m.B.State.Gender && m.A.State.Gender != GenderEnum.None && m.B.State.Gender != GenderEnum.None)
                              .OrderByDescending(m => m.Match)
                              .ToList();

                DebugLogWriteLine($"Match {string.Join(", ",userStatePairsInLobbies.Select(p=>p.User.Username))} users,\n {string.Join(", ", matches.Select(m=>m.A.User.DisplayName + ":" + m.B.User.DisplayName + " " + m.Match))} matches");
                //Move to private rooms
                bool exit = exitConditions(matches);
                while (matches.Count() > 0 && !exit)
                {
                    var pair = matches.First();
                    matches.RemoveAll(m => m.A.State == pair.A.State ||
                                      m.A.State == pair.B.State ||
                                      m.B.State == pair.A.State ||
                                      m.B.State == pair.B.State
                                      );
                    MoveToPrivateLobbyAsync(pair)
                    .ContinueWith(t => TimeoutDisband(t.Result))
                    .ConfigureAwait(false);

                    exit = exitConditions(matches);
                }
            }

            bool exitConditions(List <UsersPairMatch> matches) => (matches.All(m => m.Match == 0 || m.A.State.Gender == m.B.State.Gender));
        }
Beispiel #3
0
 private void RefreshUsersInLobbies()
 {
     UsersInLobbies.Clear();
     DateVoiceLobbies.ForEach(l => UsersInLobbies.AddRange(l.Users));
 }
Beispiel #4
0
        /// <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 ");
                    }
                }
            }
        }
Beispiel #5
0
        /// <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();
            }
        }