示例#1
0
        public void HandleDelayedCommand(string clientUniqueId, string command, List <string> parameters, Action <string> messageCallback)
        {
            TimerInfos.Remove(clientUniqueId);

            Client invoker = Parent.Client.GetClientByUniqueId(clientUniqueId);

            if (invoker == null)
            {
                string lastSeenName = Parent.Settings.LastSeenUsernames[clientUniqueId];
                messageCallback.Invoke(ColorCoder.ErrorBright($"Delayed command for {FormatCommandString(command, parameters)} was not executed as invoker {ColorCoder.Username(lastSeenName)} is no longer online"));
                return;
            }



            string commandMessage      = FormatCommandStringRaw(command, parameters);
            NotifyTextMessageEvent evt = new NotifyTextMessageEvent()
            {
                InvokerId       = invoker.Id,
                InvokerName     = invoker.Nickname,
                InvokerUniqueId = invoker.UniqueId,
                Message         = commandMessage,
            };

            messageCallback.Invoke($"Invoking command {FormatCommandString(command, parameters)} for {ColorCoder.Username(invoker.Nickname)}");
            Parent.CommandHandler.HandleTextMessage(evt, messageCallback);
        }
示例#2
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            CooldownManager.ThrowIfCooldown(evt.InvokerUniqueId, "command:daily");

            int currentBalance = EconomyManager.GetBalanceForUser(evt.InvokerUniqueId);

            if (currentBalance + Settings.DailyReward > Settings.EcoSoftBalanceLimit)
            {
                messageCallback.Invoke(ColorCoder.ErrorBright($"You would have more than {ColorCoder.Currency(Settings.EcoSoftBalanceLimit, Settings.EcoPointUnitName)}, {ColorCoder.Username(evt.InvokerName)}. Your balance: {ColorCoder.Currency(currentBalance, Settings.EcoPointUnitName)} |  Daily reward: {ColorCoder.Currency(Settings.DailyReward, Settings.EcoPointUnitName)}"));
                return;
            }


            DateTime cooldownDue = DateTime.Today.AddDays(1).AddHours(7);
            DateTime todayCheck  = DateTime.Today.AddHours(7);

            if (todayCheck > DateTime.Now)
            {
                cooldownDue = todayCheck;
            }

            CooldownManager.SetCooldown(evt.InvokerUniqueId, "command:daily", cooldownDue);

            EconomyManager.ChangeBalanceForUser(evt.InvokerUniqueId, Settings.DailyReward);
            messageCallback.Invoke(ColorCoder.SuccessDim($"{ColorCoder.Currency(Settings.DailyReward, Settings.EcoPointUnitName)} have been added to your balance as daily reward, {ColorCoder.Username(evt.InvokerName)}"));
        }
示例#3
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            if (parameters.Count == 0)
            {
                string toPrint = $"All commands are listed below ({ChatCommandHandler.ChatCommands.Count}):";
                foreach (ChatCommand cmd in ChatCommandHandler.ChatCommands.OrderBy((cmd) => cmd.CommandPrefix))
                {
                    string commandHelp = $"\n{ColorCoder.Bold($"{Settings.ChatCommandPrefix}{cmd.CommandPrefix}")}:\t-\t{cmd.GetUsageDescription(cmd.CommandPrefix, parameters)}";

                    if (!cmd.CanExecute(evt.InvokerUniqueId, cmd.CommandPrefix, parameters))
                    {
                        commandHelp = ColorCoder.ColorText(Color.LightRed, commandHelp);
                    }

                    toPrint += commandHelp;
                }

                messageCallback.Invoke(toPrint);
            }
            else
            {
                string requestedCommand = parameters[0];
                parameters = parameters.Skip(1).ToList();

                foreach (ChatCommand cmd in ChatCommandHandler.ChatCommands)
                {
                    if (cmd.CommandPrefix == requestedCommand || cmd.CommandAliases.Contains(requestedCommand))
                    {
                        ChatCommand chatCommand = (ChatCommand)Activator.CreateInstance(cmd.GetType());
                        chatCommand.Parent   = Parent;
                        chatCommand.Settings = Settings;

                        try {
                            if (!chatCommand.CanExecute(evt.InvokerUniqueId, requestedCommand, parameters))
                            {
                                messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have access to view the help of this command"));
                                break;
                            }
                            if (!chatCommand.IsValidCommandSyntax(requestedCommand, parameters))
                            {
                                //parameters = new List<string>();
                            }
                        } catch (CommandParameterInvalidFormatException) {}

                        string helpUsage       = Settings.ChatCommandPrefix + chatCommand.GetUsageSyntax(requestedCommand, parameters);
                        string helpDescription = chatCommand.GetUsageDescription(requestedCommand, parameters);
                        string aliases         = string.Join(", ", chatCommand.CommandAliases);
                        aliases = string.IsNullOrEmpty(aliases) ? "<None>" : aliases;

                        messageCallback.Invoke($"Help for command {ColorCoder.Bold($"'{chatCommand.CommandPrefix}'")}:\n\t{ColorCoder.Bold("Aliases:")} {aliases}\n\t{ColorCoder.Bold("Usage:")} {helpUsage}\n\t{ColorCoder.Bold("Description:")} {helpDescription}");
                        break;
                    }
                }
            }
        }
示例#4
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            string action     = parameters[0];
            string targetUser = parameters[1];
            Client target     = Parent.Client.GetClientByNamePart(targetUser);
            Group  group      = null;

            if (action == "add" || action == "remove")
            {
                group = AccessManager.GetGroupByName(parameters[2]);
                if (group == null)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"The group named '{ColorCoder.Bold(parameters[2])}' was not found"));
                    return;
                }
            }

            if (action == "add")
            {
                bool success = AccessManager.AddUserGroup(target.UniqueId, group);
                if (success)
                {
                    messageCallback.Invoke(ColorCoder.Success($"{ColorCoder.Username(target.Nickname)} was added to the group '{ColorCoder.Bold(group.DisplayName)}'"));
                }
                else
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"{ColorCoder.Username(target.Nickname)} is already in the group '{ColorCoder.Bold(group.DisplayName)}'"));
                }
            }
            else if (action == "remove")
            {
                bool success = AccessManager.RemoveUserGroup(target.UniqueId, group);
                if (success)
                {
                    messageCallback.Invoke(ColorCoder.Success($"{ColorCoder.Username(target.Nickname)} was removed from the group '{ColorCoder.Bold(group.DisplayName)}'"));
                }
                else
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"{ColorCoder.Username(target.Nickname)} was not in the group '{ColorCoder.Bold(group.DisplayName)}'"));
                }
            }
            else if (action == "list")
            {
                List <Group> groups  = AccessManager.GetUserGroups(target.UniqueId);
                string       toPrint = $"{ColorCoder.Username(target.Nickname)} has the following groups:";
                foreach (Group printGroup in groups)
                {
                    toPrint += $"\n\t- {printGroup.DisplayName}";
                }
                messageCallback.Invoke(toPrint);
            }
        }
示例#5
0
        public static void HandleStatsRequest(string nameSearch, int leaderboardId, Action <string> messageCallback)
        {
            AoeLeaderboardResponse response = GetLeaderboardResponse(leaderboardId, nameSearch, 2);

            if (response.Count == 0)
            {
                messageCallback.Invoke($"There were no players found on leaderboard '{leaderboardId}' with the name '{nameSearch}'");
                return;
            }
            else if (response.Count > 1)
            {
                messageCallback.Invoke($"There were multiple players found on leaderboard '{leaderboardId}' with the name '{nameSearch}'");
                return;
            }

            AoePlayer player          = response.Leaderboard[0];
            string    clanAddition    = player.Clan == null ? "" : $"[{player.Clan}]";
            string    leaderboardName = Leaderboards.First(kv => kv.Value == leaderboardId).Key;
            int       ratingDiff      = player.Rating.Value - player.PreviousRating.Value;
            string    ratingDiffStr   = ratingDiff < 0 ? ColorCoder.ErrorBright(ratingDiff) : ratingDiff > 0 ? ColorCoder.SuccessDim(ratingDiff) : $"{ratingDiff}";
            double    ratioPercent    = (double)player.Wins.Value * 100 / player.Games.Value;
            string    ratioPercentStr = $"{ratioPercent:0.##}%";

            ratioPercentStr = ratioPercent < 50 ? ColorCoder.ErrorBright(ratioPercentStr) : ratioPercent > 50 ? ColorCoder.SuccessDim(ratioPercentStr) : $"{ratioPercentStr}";


            string toPrint = $"{ColorCoder.Bold(leaderboardName.ToUpper())} stats for {ColorCoder.Bold(player.Name+clanAddition)}:";

            toPrint += $"\n\tRating: {ColorCoder.Bold(player.Rating.Value)} ({ratingDiffStr}) (#{player.Rank})";
            toPrint += $"\n\tPeak Rating: {player.HighestRating}";
            toPrint += $"\n\tStreak: {player.Streak} | Lowest: {player.LowestStreak} | Highest: {player.HighestStreak}";
            toPrint += $"\n\tGames: {player.Games} ({ColorCoder.SuccessDim(player.Wins.Value+"W")} - {ColorCoder.ErrorBright(player.Losses.Value+"L")} | {ratioPercentStr})";
            toPrint += $"\n\tCountry: {player.Country}";

            messageCallback.Invoke(toPrint);
        }
示例#6
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            // +----------------------+
            // | Administrative Block |
            // +----------------------+
            if (IsAdministrativeCommand)
            {
                if (AdminAction == "add-file")
                {
                    AddPlaysound(AdminPlaysoundName, AdminPlaysoundPrice, AdminPlaysoundFileName, AdminPlaysoundSource, messageCallback);
                }
                else if (AdminAction == "add-yt")
                {
                }
                else if (AdminAction == "remove")
                {
                    RemovePlaysound(AdminPlaysoundName, messageCallback);
                }
                else if (AdminAction == "add-modifier")
                {
                }
                else if (AdminAction == "list-devices")
                {
                    string devices = string.Join("\n\t", AudioHelper.GetAudioDevices());
                    messageCallback.Invoke($"All audio devices:\n\t{devices}");
                }
                else if (AdminAction == "stop-sounds")
                {
                    int killed = 0;
                    foreach (Process p in AllStartedSoundProcesses)
                    {
                        if (!p.HasExited)
                        {
                            p.Kill();
                            killed++;
                        }
                    }
                    AllStartedSoundProcesses.Clear();

                    messageCallback.Invoke(ColorCoder.ErrorBright($"Killed {ColorCoder.Bold($"'{killed}'")} audio process(es)"));
                }
                return;
            }


            if (parameters.Count == 2 && parameters[0] == "price")
            {
                int price = CalculateYoutubePlaysoundCost(PriceLookupDuration);
                messageCallback.Invoke($"Cost for {ColorCoder.Bold($"'{PriceLookupDuration}'")} seconds of a youtube video: {ColorCoder.Currency(price)}");
                return;
            }



            // +----------------------+
            // |      Pagination      |
            // +----------------------+
            if (HasRequestedPagination)
            {
                int entriesPerPage = Settings.PlaysoundsSoundsPerPage;
                int maxPage        = (int)Math.Ceiling((double)Settings.PlaysoundsSavedSounds.Count / entriesPerPage);

                if (RequestedPage < 1 || RequestedPage > maxPage)
                {
                    messageCallback.Invoke($"The page '{RequestedPage}' is not in the valid range of [1 to {maxPage}]!");
                    return;
                }

                int pageIndex             = (int)RequestedPage - 1;
                int skipValues            = pageIndex * entriesPerPage;
                List <Playsound> thisPage = Settings.PlaysoundsSavedSounds.OrderBy(ps => ps.BasePrice).ThenBy(ps => ps.Name).Skip(skipValues).Take(entriesPerPage).ToList();

                string toPrint = "";
                foreach (Playsound listSound in thisPage)
                {
                    toPrint += $"\n'{listSound.Name}'\t({listSound.BasePrice} {Settings.EcoPointUnitName})";
                }
                toPrint += $"\n\t\t\t{ColorCoder.Bold($"-\tPage ({RequestedPage}/{maxPage})\t-")}";
                toPrint += $"\n\nTo switch pages write '{Settings.ChatCommandPrefix}{command} <1/2/3/...>'";

                messageCallback.Invoke(toPrint);

                return;
            }


            if (evt.TargetMode != TSClient.Enums.MessageMode.Channel)
            {
                messageCallback.Invoke(ColorCoder.Error("Playsounds can only be used in channel chats!"));
                return;
            }

            Client myClient = Parent.Client.GetClientById(Parent.MyClientId);

            if (Parent.Client.IsClientOutputMuted(myClient))
            {
                messageCallback.Invoke(ColorCoder.Error("This doesn't work right now..."));
                return;
            }
            if (Parent.Client.IsClientInputMuted(myClient))
            {
                messageCallback.Invoke(ColorCoder.Error("Host is muted, playsound can still be played but others won't hear it (@Panther)"));
            }

            CooldownManager.ThrowIfCooldown(evt.InvokerUniqueId, "command:playsounds");


            // +-------------------------+
            // | Playback of local files |
            // +-------------------------+



            if (!CheckValidModifiers(ManualModifiers, messageCallback))
            {
                return;
            }

            double speed = 1.0, pitch = 1.0, volume = 1.0;

            if (SelectedModifier != null)
            {
                Dictionary <string, double> modifiers = Settings.PlaysoundsModifiers[SelectedModifier];
                if (modifiers.ContainsKey(ModifierNameSpeed))
                {
                    speed = modifiers[ModifierNameSpeed];
                }
                if (modifiers.ContainsKey(ModifierNamePitch))
                {
                    pitch = modifiers[ModifierNamePitch];
                }
                if (modifiers.ContainsKey(ModifierNameVolume))
                {
                    volume = modifiers[ModifierNameVolume];
                }
            }

            if (ManualModifiers != null)
            {
                if (ManualModifiers.ContainsKey(ModifierNameSpeed))
                {
                    speed = ManualModifiers[ModifierNameSpeed];
                }
                if (ManualModifiers.ContainsKey(ModifierNamePitch))
                {
                    pitch = ManualModifiers[ModifierNamePitch];
                }
                if (ManualModifiers.ContainsKey(ModifierNameVolume))
                {
                    volume = ManualModifiers[ModifierNameVolume];
                }
            }

            Dictionary <string, double> actualModifiers = new Dictionary <string, double>()
            {
                [ModifierNameSpeed]  = speed,
                [ModifierNamePitch]  = pitch,
                [ModifierNameVolume] = volume,
            };

            double priceFactor = GetPriceFactorForModifiers(actualModifiers);


            int    basePrice;
            string filePath;
            double baseDuration;
            string playingSoundStr;

            if (SourceIsYoutube)
            {
                // +----------------------+
                // |   Youtube fetching   |
                // +----------------------+
                if (SoundSource.ToLower().StartsWith("[url]"))
                {
                    SoundSource = Utils.RemoveTag(SoundSource, "url");
                }
                string title      = "";
                string youtubeUrl = AudioHelper.IsYouTubeVideoUrl(SoundSource);
                if (youtubeUrl != null)
                {
                    lock (YoutubeDownloadLock) {
                        if (IsLoadingYoutubeAudio)
                        {
                            string loadingStr = LoadingPercentDone == -1 ? "download not yet started" : $"{LoadingPercentDone:0.##}%";
                            messageCallback.Invoke(ColorCoder.ErrorBright($"Chill, I'm still loading another clip... ({loadingStr})"));
                            return;
                        }
                        IsLoadingYoutubeAudio = true;
                    }

                    string videoId = youtubeUrl.Substring(youtubeUrl.IndexOf($"v=") + 2, 11);
                    try {
                        (filePath, title) = AudioHelper.LoadYoutubeVideo(videoId, (int)YoutubeStartTime, (int)(YoutubeEndTime - YoutubeStartTime) + 1, new ProgressSaver());
                        Parent.UpdateYoutubeFolderSize();
                    } catch (ArgumentException ex) {
                        messageCallback.Invoke(ColorCoder.ErrorBright($"Error with youtube video: {ex.Message}"));
                        lock (YoutubeDownloadLock) {
                            IsLoadingYoutubeAudio = false;
                            LoadingPercentDone    = -1;
                        }
                        return;
                    }

                    lock (YoutubeDownloadLock) {
                        IsLoadingYoutubeAudio = false;
                        LoadingPercentDone    = -1;
                    }
                }
                else
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"The URL is not a youtube link..."));
                    return;
                }

                baseDuration = AudioHelper.GetAudioDurationInSeconds(filePath);
                if (double.IsNaN(baseDuration))
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"Couldn't get audio duration from file '{filePath}'"));
                    return;
                }

                basePrice = CalculateYoutubePlaysoundCost(baseDuration);
                if (baseDuration <= 60 && Settings.PlaysoundsYoutubeOnePointEvent)
                {
                    basePrice = 1;
                }

                playingSoundStr = ColorCoder.SuccessDim($" Playing YouTube clip {ColorCoder.Bold($"'{title}'")} [{TimeSpan.FromSeconds((int)baseDuration)}].");
            }
            else
            {
                Playsound sound;
                if (SoundSource == "random")
                {
                    Random r = new Random();
                    sound = Settings.PlaysoundsSavedSounds.FindAll(ps => Math.Ceiling(ps.BasePrice * priceFactor) <= EconomyManager.GetBalanceForUser(evt.InvokerUniqueId)).OrderBy(ps => r.Next()).First();
                }
                else
                {
                    List <Playsound> sounds = Settings.PlaysoundsSavedSounds.FindAll(ps => ps.Name.ToLower().Contains(SoundSource.ToLower()));

                    //Fix for matching the exact sound name
                    Playsound exactSound = Settings.PlaysoundsSavedSounds.Find(ps => ps.Name == SoundSource);
                    if (exactSound != null)
                    {
                        sounds.Clear();
                        sounds.Add(exactSound);
                    }

                    if (sounds.Count == 0)
                    {
                        messageCallback.Invoke(ColorCoder.Error($"A playsound with the name {ColorCoder.Bold($"'{SoundSource}'")} wasn't found!"));
                        return;
                    }
                    else if (sounds.Count > 1)
                    {
                        string soundsJoined = string.Join(", ", sounds.Select(ps => ColorCoder.Bold($"'{ps.Name}'")));
                        messageCallback.Invoke(ColorCoder.Error($"Multiple sounds with {ColorCoder.Bold($"'{SoundSource}'")} in their name were found: ({soundsJoined})"));
                        return;
                    }
                    else
                    {
                        sound = sounds[0];
                    }
                }

                basePrice       = sound.BasePrice;
                filePath        = Utils.GetProjectFilePath($"{SoundsFolder}\\{sound.FileName}");
                baseDuration    = AudioHelper.GetAudioDurationInSeconds(filePath);
                playingSoundStr = ColorCoder.SuccessDim($" Playing sound {ColorCoder.Bold($"'{sound.Name}'")}.");
            }



            int    modifiedPrice    = Math.Max(1, (int)Math.Round(basePrice * priceFactor));
            double modifiedDuration = baseDuration / speed;

            int balanceAfter = EconomyManager.GetUserBalanceAfterPaying(evt.InvokerUniqueId, modifiedPrice);

            if (balanceAfter < 0)
            {
                messageCallback.Invoke(ColorCoder.Error($"You dont have enough cash for that sound, {ColorCoder.Username(evt.InvokerName)}. Price: {ColorCoder.Currency(modifiedPrice, Settings.EcoPointUnitName)}, Needed: {ColorCoder.Currency(-balanceAfter, Settings.EcoPointUnitName)}"));
                return;
            }

            CooldownManager.SetCooldown(evt.InvokerUniqueId, "command:playsounds", CalculateCooldown(modifiedDuration));

            EconomyManager.ChangeBalanceForUser(evt.InvokerUniqueId, -modifiedPrice);

            string usernameStr      = ColorCoder.Username(evt.InvokerName);
            string priceAdditionStr = priceFactor == 1 ? "" : $" x{priceFactor:0.##} = -{modifiedPrice}";
            string balanceStr       = $"Your balance: {EconomyManager.GetBalanceForUser(evt.InvokerUniqueId)} {Settings.EcoPointUnitName} {ColorCoder.ErrorBright($"(-{basePrice}{priceAdditionStr})")}";

            messageCallback.Invoke($"{usernameStr} {playingSoundStr} {balanceStr}");

            Process audioProcess = AudioHelper.PlayAudio(filePath, volume, speed, pitch, audioDevice: Settings.PlaysoundsSoundDevice);

            AllStartedSoundProcesses.Add(audioProcess);
        }
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            Client target = null;

            if (TargetName != null)
            {
                target = Parent.Client.GetClientByNamePart(TargetName);
            }

            if (target == null)
            {
                target = Parent.Client.GetClientById(evt.InvokerId);
            }

            if (IsSendingBalance)
            {
                if (SendParam == "all")
                {
                    SendAmount = (uint)Math.Max(0, EconomyManager.GetBalanceForUser(evt.InvokerUniqueId));
                }
                else if (SendParam == "excess")
                {
                    int tempB = EconomyManager.GetBalanceForUser(evt.InvokerUniqueId);
                    if (tempB > Settings.EcoSoftBalanceLimit)
                    {
                        SendAmount = (uint)(tempB - Settings.EcoSoftBalanceLimit);
                    }
                    else
                    {
                        SendAmount = 0;
                    }
                }

                if (SendAmount == 0)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"Why would you want to send {ColorCoder.Currency(0)}? What are you, stupid {ColorCoder.Username(evt.InvokerName)}"));
                    return;
                }
                else if (EconomyManager.GetUserBalanceAfterPaying(evt.InvokerUniqueId, (int)SendAmount) < 0)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"You can't afford to send that much cash, {ColorCoder.Username(evt.InvokerName)}"));
                    return;
                }
                else if (EconomyManager.GetUserBalanceAfterPaying(target.UniqueId, -1 * (int)SendAmount) > Settings.EcoSoftBalanceLimit)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"You can't send that much cash because {ColorCoder.Username(target.Nickname)} would have more than '{ColorCoder.Currency(Settings.EcoSoftBalanceLimit)}'"));
                    return;
                }

                EconomyManager.ChangeBalanceForUser(evt.InvokerUniqueId, (-1) * (int)SendAmount);
                EconomyManager.ChangeBalanceForUser(target.UniqueId, (int)SendAmount);

                messageCallback.Invoke(ColorCoder.SuccessDim($"Sent '{ColorCoder.Currency(SendAmount)}' to {ColorCoder.Username(target.Nickname)}"));
            }
            else if (command == "setbalance")
            {
                int setAmount = SetAmount;
                if (SetAmountIsRelative)
                {
                    setAmount += EconomyManager.GetBalanceForUser(target.UniqueId);
                }

                EconomyManager.SetBalanceForUser(target.UniqueId, setAmount);
                int setTo = EconomyManager.GetBalanceForUser(target.UniqueId);
                messageCallback.Invoke(ColorCoder.Success($"Set balance for {ColorCoder.Username(target.Nickname)} to {ColorCoder.Bold($"{setTo} {Settings.EcoPointUnitName}")}"));
            }
            else
            {
                int max     = Settings.EcoSoftBalanceLimit;
                int balance = EconomyManager.GetBalanceForUser(target.UniqueId);
                messageCallback.Invoke($"Balance of {ColorCoder.Username(target.Nickname)}: {ColorCoder.Bold(balance.ToString())} / {ColorCoder.Bold($"{max} {Settings.EcoPointUnitName}")}");
            }
        }
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            if (command != CommandPrefix)
            {
                if (!Settings.DynamicCommands.ContainsKey(command.ToLower()))
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"The command {command} was not found in the dynamic commands list (should never happen)"));
                }

                string parametersJoined = string.Join(" ", parameters);
                string toPrint          = Settings.DynamicCommands[command.ToLower()];
                toPrint = toPrint.Replace("{params}", parametersJoined);
                messageCallback.Invoke(toPrint);
                return;
            }

            string action      = parameters[0];
            string commandName = "";
            string commandText = "";

            if (action == "add")
            {
                commandName = parameters[1];
                commandText = string.Join(" ", parameters.Skip(2));
            }
            else if (action == "remove")
            {
                commandName = parameters[1];
            }

            commandName = commandName.ToLower();


            if (action == "add")
            {
                if (Settings.DynamicCommands.ContainsKey(commandName))
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"The command {ColorCoder.Bold($"'{commandName}'")} already exists."));
                    return;
                }

                Settings.DynamicCommands.Add(commandName, commandText);
                messageCallback.Invoke(ColorCoder.Success($"Added command {ColorCoder.Bold($"'{commandName}'")}."));
                Settings.DelayedSave();
            }
            else if (action == "remove")
            {
                if (!Settings.DynamicCommands.ContainsKey(commandName))
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"The command {ColorCoder.Bold($"'{commandName}'")} does not exists."));
                    return;
                }

                Settings.DynamicCommands.Remove(commandName);
                messageCallback.Invoke(ColorCoder.Success($"Removed command {ColorCoder.Bold($"'{commandName}'")}."));
                Settings.DelayedSave();
            }
            else if (action == "list")
            {
                if (Settings.DynamicCommands.Count == 0)
                {
                    messageCallback.Invoke($"The dynamic commands list is currently empty.");
                    return;
                }


                string toPrint = $"These are all registered commands ({Settings.DynamicCommands.Count}):";
                foreach (string dynCommand in Settings.DynamicCommands.Keys.OrderBy(s => s))
                {
                    string dynCommandText = Settings.DynamicCommands[dynCommand];
                    toPrint += $"\n\t{ColorCoder.Bold($"'{dynCommand}'")}: {dynCommandText}";
                }

                messageCallback.Invoke(toPrint);
            }
        }
示例#9
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            if (Action == "status")
            {
                if (TimerInfos.ContainsKey(evt.InvokerUniqueId))
                {
                    (Timer targetTimer, DateTime timeDue, string targetCommand, List <string> targetParameters) = TimerInfos[evt.InvokerUniqueId];

                    TimeSpan timeLeft = timeDue - DateTime.Now;
                    timeLeft = TimeSpan.FromSeconds((int)timeLeft.TotalSeconds);

                    messageCallback.Invoke($"{ColorCoder.Username(evt.InvokerName)}: Time left for {FormatCommandString(command, parameters)}: [{timeLeft}]");
                }
                else
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have an active timed command, {ColorCoder.Username(evt.InvokerName)}"));
                }
                return;
            }
            else if (Action == "cancel")
            {
                if (TimerInfos.ContainsKey(evt.InvokerUniqueId))
                {
                    (Timer targetTimer, DateTime timeDue, string targetCommand, List <string> targetParameters) = TimerInfos[evt.InvokerUniqueId];

                    targetTimer.Dispose();
                    TimerInfos.Remove(evt.InvokerUniqueId);

                    messageCallback.Invoke($"{ColorCoder.Username(evt.InvokerName)}: Your timer for {FormatCommandString(command, parameters)} was cancelled!");
                }
                else
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have an active timed command, {ColorCoder.Username(evt.InvokerName)}"));
                }
                return;
            }



            if (TimerInfos.ContainsKey(evt.InvokerUniqueId))
            {
                messageCallback.Invoke(ColorCoder.ErrorBright($"You already have an active timed command, {ColorCoder.Username(evt.InvokerName)}"));
                return;
            }

            TimeDelta = TimeDelta.Duration();
            ChatCommand commandToExecute;

            try {
                commandToExecute = Parent.CommandHandler.GetCommandForMessage(TargetCommand, TargetParameters.AsEnumerable().ToList(), evt.InvokerUniqueId);
            } catch (Exception) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"Could not parse the desired command. Make sure you have access to the command and the syntax is valid!"));
                return;
            }

            Timer timer = new Timer(new TimerCallback((state) => {
                HandleDelayedCommand(evt.InvokerUniqueId, TargetCommand, TargetParameters, messageCallback);
            }), null, TimeDelta, TimeSpan.FromMilliseconds(-1));

            TimerInfos.Add(evt.InvokerUniqueId, Tuple.Create(timer, DateTime.Now + TimeDelta, TargetCommand, TargetParameters));

            messageCallback.Invoke(ColorCoder.SuccessDim($"Invoking command {FormatCommandString(TargetCommand, TargetParameters)} in [{ColorCoder.Bold(TimeDelta)}], {ColorCoder.Username(evt.InvokerName)}"));
        }
示例#10
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            lock (LockObject) {
                if (IsBusy)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright("The fetcher is busy, try again when the current request has completed..."));
                    return;
                }
                IsBusy = true;
            }

            Elos = Parent.EloSettings;
            if (Elos.LastUpdated + Elos.UpdateFrequency < DateTime.Now)
            {
                messageCallback.Invoke($"Leaderboards were outdated (older than 1 month), started refreshing cache. This could take a few minutes...");

                Parent.LogMessage("[*] Starting fetch AoE2DE leaderboards...");
                foreach (string mode in LeaderboardIds.Keys)
                {
                    FetchClientList(mode, messageCallback);
                    Parent.LogMessage($"[*] {mode} done");
                }
                Parent.LogMessage("[*] AoE2DE leaderboards fetch done");

                //Implicitly saves the elos to the hard drive
                Elos.LastUpdated = DateTime.Now;
            }


            //HttpClient client = new HttpClient();
            SelectedLeaderboard = SelectedLeaderboard ?? ModeTgName;
            int fromElo, toElo;

            if (!string.IsNullOrEmpty(SelectedLevel))
            {
                (fromElo, toElo) = EloRanges[SelectedLeaderboard][SelectedLevel];
                if (fromElo == -1)
                {
                    fromElo = Elos.AllPlayersElos[SelectedLeaderboard].Last().Item1;
                }
                if (toElo == -1)
                {
                    toElo = Elos.AllPlayersElos[SelectedLeaderboard].First().Item1;
                }
            }
            else if (InputFromElo != uint.MaxValue)
            {
                if (InputFromElo > InputToElo)
                {
                    uint tempElo = InputFromElo;
                    InputFromElo = InputToElo;
                    InputToElo   = tempElo;
                }

                fromElo = Math.Max((int)InputFromElo, Elos.AllPlayersElos[SelectedLeaderboard].Last().Item1);
                toElo   = Math.Min((int)InputToElo, Elos.AllPlayersElos[SelectedLeaderboard].First().Item1);
            }
            else
            {
                fromElo = EloRanges[SelectedLeaderboard]["lel"].Item1;
                toElo   = EloRanges[SelectedLeaderboard]["good"].Item2;
            }

            Random r      = new Random();
            int    offset = r.Next(1, 10);

            int lowerRankIndex = int.MaxValue, upperRankIndex = int.MinValue; //indices inclusive bounds
            List <Tuple <int, string> > leaderboard = Elos.AllPlayersElos[SelectedLeaderboard];

            for (int i = 0; i < leaderboard.Count; i++)
            {
                Tuple <int, string> position = leaderboard[i];
                if (upperRankIndex == int.MinValue && position.Item1 <= toElo)
                {
                    upperRankIndex = i;
                }
                if (lowerRankIndex == int.MaxValue && position.Item1 < fromElo)
                {
                    lowerRankIndex = i - 1;
                }
            }


            bool   hasFoundMatch = false;
            string downloadLink  = "";

            while (!hasFoundMatch)
            {
                int    selectedIndex = r.Next(upperRankIndex, lowerRankIndex + 1);
                string steamId       = Elos.AllPlayersElos[SelectedLeaderboard][selectedIndex].Item2;

                string fetchUrl = $"https://aoe2.net/api/player/matches?game=aoe2de&steam_id={steamId}&count=10&start=1";

                HttpClient          client   = new HttpClient();
                HttpResponseMessage response = client.GetAsync(fetchUrl).Result;
                string content = response.Content.ReadAsStringAsync().Result;

                JArray  matches    = JArray.Parse(content);
                JObject foundMatch = null;

                foreach (JToken matchToken in matches.Children())
                {
                    JObject match       = (JObject)matchToken;
                    bool    isRanked    = match.GetValue("ranked").ToObject <bool>();
                    int     playerCount = match.GetValue("num_players").ToObject <int>();

                    if (!isRanked)
                    {
                        Parent.LogMessage("Game was not ranked, skipping...");
                        continue;
                    }

                    if ((SelectedLeaderboard == Mode1v1Name && playerCount == 2) || (SelectedLeaderboard == ModeTgName && playerCount > 2))
                    {
                        foundMatch = match;
                    }
                    else
                    {
                        Parent.LogMessage($"Game was not of leaderboard '{SelectedLeaderboard}', skipping...");
                    }
                }

                if (foundMatch == null)
                {
                    Parent.LogMessage($"Randomly selected player did not play a ranked '{SelectedLeaderboard}' game in the last 10 games");
                    continue;
                }

                string  matchId     = foundMatch.GetValue("match_id").ToObject <string>();
                JArray  players     = foundMatch.GetValue("players").ToObject <JArray>();
                JObject firstPlayer = (JObject)players[0];

                long profileId = firstPlayer.GetValue("profile_id").ToObject <long>();
                downloadLink  = $"https://aoe.ms/replay/?gameId={matchId}&profileId={profileId}";
                hasFoundMatch = true;
            }

            messageCallback.Invoke($"Here is your {ColorCoder.Bold(SelectedLeaderboard.ToUpper())} replay of elo range ({fromElo}-{toElo}): [url={downloadLink}]Download[/url]");

            lock (LockObject) {
                IsBusy = false;
            }
        }
示例#11
0
 public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
 {
     messageCallback.Invoke(ColorCoder.ErrorBright("Plugin instance was killed!"));
     Messenger.Default.Send(new StopApplicationMessage());
 }
示例#12
0
        public static void HandleLastMatchRequest(string nameSearch, int leaderboardId, Action <string> messageCallback)
        {
            AoeLeaderboardResponse response = GetLeaderboardResponse(leaderboardId, nameSearch, 2);
            AoePlayer player;

            if (response.Count == 0)
            {
                messageCallback.Invoke($"There were no players found on leaderboard '{leaderboardId}' with the name '{nameSearch}'");
                return;
            }
            else if (response.Count > 1)
            {
                messageCallback.Invoke($"There were multiple players found on leaderboard '{leaderboardId}' with the name '{nameSearch}', taking the highest rated player...");
                player = response.Leaderboard[0];
            }
            else
            {
                player = response.Leaderboard[0];
            }


            AoeLastMatchResponse lastMatchResponse = GetLastMatchResponse(player.SteamId);
            Match lastMatch = lastMatchResponse.LastMatch;
            Dictionary <int, List <List <AoePlayer> > > matchTeams = new Dictionary <int, List <List <AoePlayer> > >();

            foreach (AoePlayer matchPlayer in lastMatch.Players)
            {
                if (!matchTeams.ContainsKey(matchPlayer.Team.Value))
                {
                    matchTeams.Add(matchPlayer.Team.Value, new List <List <AoePlayer> >());
                }
                List <List <AoePlayer> > team       = matchTeams[matchPlayer.Team.Value];
                List <AoePlayer>         playerInfo = new List <AoePlayer>();
                playerInfo.Add(matchPlayer);

                if (matchPlayer.SteamId != player.SteamId)
                {
                    AoeLeaderboardResponse lb = GetLeaderboardResponse(leaderboardId, matchPlayer.ProfileId.Value.ToString(), 2, isProfileId: true);
                    if (lb.Leaderboard.Count == 0)
                    {
                        playerInfo.Add(null);
                    }
                    else
                    {
                        playerInfo.Add(lb.Leaderboard[0]);
                    }
                }
                else
                {
                    playerInfo.Add(player);
                }
                team.Add(playerInfo);
            }

            string toPrint = "";

            toPrint += lastMatch.Finished.HasValue ? "Last Match (" + (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(lastMatch.Finished.Value).ToLocalTime()).ToString("dd.MM.yy HH:mm") + "):" : "Current Match:";
            toPrint += lastMatch.Ranked.HasValue && lastMatch.Ranked.Value ? " Ranked" : " Unranked";
            string mapName = GetAoeString("map_type", lastMatch.MapType.Value);

            toPrint += $" on {mapName}";

            bool firstTeam = true;

            foreach (int teamPos in matchTeams.Keys)
            {
                List <List <AoePlayer> > team = matchTeams[teamPos];

                string winStatusString;
                if (!team[0][0].Won.HasValue)
                {
                    winStatusString = "◯";
                }
                else if (team[0][0].Won.Value)
                {
                    winStatusString = "👑";
                }
                else
                {
                    winStatusString = "☠";
                }

                if (firstTeam)
                {
                    firstTeam = false;
                }
                else
                {
                    toPrint += "\n\t\tvs.";
                }

                foreach (List <AoePlayer> playerInfo in team)
                {
                    string playerName = playerInfo[0].Name;
                    string civ        = GetAoeString("civ", playerInfo[0].Civ.Value);

                    if (playerName.ToLower().Contains(nameSearch.ToLower()))
                    {
                        playerName = ColorCoder.Bold(playerName);
                    }

                    if (playerInfo[1] == null) //Player is not yet ranked in this leaderboard
                    {
                        string line = $"\n{winStatusString} [--] {playerName} (<placements>) on {civ}";
                        toPrint += line;
                    }
                    else
                    {
                        string country = playerInfo[1].Country;
                        string rating  = playerInfo[1].Rating.HasValue ? $"{playerInfo[1].Rating.Value}" : "<placement>";
                        int    games   = playerInfo[1].Games.Value;
                        int    wins    = playerInfo[1].Wins.Value;

                        double ratioPercent    = Math.Round((double)wins * 100 / games);
                        string ratioPercentStr = $"{ratioPercent}%";
                        ratioPercentStr = ratioPercent < 50 ? ColorCoder.ErrorBright(ratioPercentStr) : ratioPercent > 50 ? ColorCoder.SuccessDim(ratioPercentStr) : $"{ratioPercentStr}";

                        string line = $"\n{winStatusString} [{country}] {playerName} ({rating}, {games} G, {ratioPercentStr}) on {civ}";
                        toPrint += line;
                    }
                }
            }

            messageCallback.Invoke(toPrint);
        }
示例#13
0
        public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback)
        {
            int amountToGamble      = 0;
            StatisticSettings stats = Parent.StatSettings;

            if (RequestedStats)
            {
                RouletteStatistics displayStats;
                string             toPrint;

                if (RequestedStatsName != null && RequestedStatsName == "all")
                {
                    displayStats = stats.Roulette;
                    toPrint      = "Global roulette stats:";
                }
                else
                {
                    string userUid  = evt.InvokerUniqueId;
                    string userName = evt.InvokerName;

                    if (RequestedStatsName != null)
                    {
                        Client user = Parent.Client.GetClientByNamePart(RequestedStatsName);
                        userUid  = user.UniqueId;
                        userName = user.Nickname;
                    }

                    CheckHasStatisticsEntry(userUid);
                    displayStats = stats.RouletteIndividual[userUid];
                    toPrint      = $"Roulette stats for {ColorCoder.Username(userName)}:";
                }

                int    won          = displayStats.GamesWon;
                int    lost         = displayStats.GamesLost;
                double ratioPercent = (double)won * 100 / (lost + won);
                string ratioPercentStr;
                if (double.IsNaN(ratioPercent))
                {
                    ratioPercentStr = "-%";
                }
                else
                {
                    ratioPercentStr = ColorCoder.ColorPivotPercent(ratioPercent, 50);
                }
                toPrint += $"\n\tGames: {won + lost} ({ColorCoder.SuccessDim($"{won}W")}, {ColorCoder.ErrorBright($"{lost}L")} | {ratioPercentStr})";

                int    balanceWon     = displayStats.PointsWon;
                int    balanceLost    = displayStats.PointsLost;
                int    balanceDiff    = balanceWon - balanceLost;
                string balanceDiffStr = ColorCoder.ColorPivot(balanceDiff, 0);
                toPrint += $"\n\tPoints: {balanceDiffStr} ({ColorCoder.SuccessDim($"+{balanceWon} won")}, {ColorCoder.ErrorBright($"-{balanceLost} lost")})";

                int jackpots      = displayStats.Jackpots;
                int jackpotPoints = displayStats.JackpotsPointsWon;
                toPrint += $"\n\tJackpots: {jackpots} ({ColorCoder.SuccessDim($"+{jackpotPoints} bonus")})";

                double rolls    = displayStats.Rolls;
                string rollsStr = (won + lost) == 0 ? "-" : $"{rolls / (won + lost):0.####}";
                toPrint += $"\n\tAvg. Roll: {rollsStr}";

                messageCallback.Invoke(toPrint);
                return;
            }


            if (!Settings.RouletteEnabled)
            {
                messageCallback.Invoke(ColorCoder.ErrorBright($"The casino is currently closed, sorry {ColorCoder.Username(evt.InvokerName)}!"));
                return;
            }

            CooldownManager.ThrowIfCooldown(evt.InvokerUniqueId, "command:roulette");

            int currentBalance = EconomyManager.GetBalanceForUser(evt.InvokerUniqueId);

            if (currentBalance > Settings.EcoSoftBalanceLimit)
            {
                messageCallback.Invoke(ColorCoder.ErrorBright($"You can't gamble while being over {ColorCoder.Bold($"{Settings.EcoSoftBalanceLimit} {Settings.EcoPointUnitName}")}, {ColorCoder.Username(evt.InvokerName)}"));
                return;
            }

            if (IsAll)
            {
                amountToGamble = EconomyManager.GetBalanceForUser(evt.InvokerUniqueId);
            }
            else if (IsPercent)
            {
                if (Amount > 100)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"You can't gamble away more than you own, {ColorCoder.Username(evt.InvokerName)}"));
                    return;
                }

                amountToGamble = EconomyManager.GetBalanceForUser(evt.InvokerUniqueId);
                amountToGamble = (int)Math.Ceiling(amountToGamble * ((double)Amount / 100));
            }
            else
            {
                int balanceAfterPay = EconomyManager.GetUserBalanceAfterPaying(evt.InvokerUniqueId, (int)Amount);
                if (balanceAfterPay < 0)
                {
                    messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have enough to gamble away '{ColorCoder.Bold($"{Amount} {Settings.EcoPointUnitName}")}', {ColorCoder.Username(evt.InvokerName)}"));
                    return;
                }

                amountToGamble = (int)Amount;
            }

            if (amountToGamble <= 0)
            {
                messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have any cash on you, get out of my casino!"));
                return;
            }

            CooldownManager.SetCooldown(evt.InvokerUniqueId, "command:roulette", Settings.RouletteCooldown);


            double winChancePercent     = Settings.RouletteWinChancePercent;
            double jackpotChancePercent = Settings.RouletteJackpotChancePercent;

            if (amountToGamble == Settings.EcoSoftBalanceLimit)
            {
                winChancePercent += 1;
            }

            winChancePercent     /= 100;
            jackpotChancePercent /= 100;

            Random r           = new Random();
            double chosenValue = r.NextDouble();

            string resultLogMsg = $"({chosenValue:0.#####} | win {winChancePercent:0.#####} | jackpot {jackpotChancePercent:0.#####})";

            Parent.LastRouletteResult = resultLogMsg;
            Parent.LogMessage($"Roulette result: {resultLogMsg}");

            int    changeBalanceAmount;
            string message;
            string ptsUnit = Settings.EcoPointUnitName;

            CheckHasStatisticsEntry(evt.InvokerUniqueId);
            RouletteStatistics indivStats = stats.RouletteIndividual[evt.InvokerUniqueId];
            RouletteStatistics allStats   = stats.Roulette;

            allStats.Rolls   += chosenValue;
            indivStats.Rolls += chosenValue;

            if (chosenValue < winChancePercent)   //User won the roulette

            {
                double yield = Settings.RouletteWinYieldMultiplier;
                changeBalanceAmount = (int)Math.Floor(amountToGamble * (yield - 1));

                if (chosenValue < jackpotChancePercent)
                {
                    allStats.Jackpots++;
                    int jackpotPoints = (int)(changeBalanceAmount * Settings.RouletteJackpotMultiplier);

                    allStats.JackpotsPointsWon   += jackpotPoints - changeBalanceAmount;
                    indivStats.JackpotsPointsWon += jackpotPoints - changeBalanceAmount;

                    changeBalanceAmount = jackpotPoints;
                    messageCallback.Invoke(ColorCoder.Success($"\t-\t JACKPOT! Your reward has just been tripled!\t-\t"));
                }

                allStats.GamesWon++;
                indivStats.GamesWon++;
                allStats.PointsWon   += changeBalanceAmount;
                indivStats.PointsWon += changeBalanceAmount;
                message = ColorCoder.ColorText(Color.DarkGreen, ColorCoder.Username(evt.InvokerName) + $" won {ColorCoder.Bold(changeBalanceAmount.ToString())} {ptsUnit} in roulette and now has {ColorCoder.Bold((currentBalance + changeBalanceAmount).ToString())} {ptsUnit} forsenPls ({chosenValue:0.####})");
            }
            else
            {
                changeBalanceAmount = -amountToGamble;
                allStats.GamesLost++;
                indivStats.GamesLost++;
                allStats.PointsLost   += amountToGamble;
                indivStats.PointsLost += amountToGamble;
                message = ColorCoder.ErrorBright(ColorCoder.Username(evt.InvokerName) + $" lost {ColorCoder.Bold(amountToGamble.ToString())} {ptsUnit} in roulette and now has {ColorCoder.Bold((currentBalance + changeBalanceAmount).ToString())} {ptsUnit} FeelsBadMan ({chosenValue:0.####})");
            }

            stats.DelayedSave();

            EconomyManager.ChangeBalanceForUser(evt.InvokerUniqueId, changeBalanceAmount);
            messageCallback.Invoke(message);
        }
        public bool HandleTextMessage(NotifyTextMessageEvent evt, Action <string> messageCallback)
        {
            if (!Settings.ChatCommandsEnabled || string.IsNullOrEmpty(evt.Message) || !evt.Message.StartsWith(Settings.ChatCommandPrefix))
            {
                return(false);
            }

            Parent.LogMessage($"{evt.InvokerName} requested command: \"{evt.Message}\"");

            //Copy event as to not mess up other event handlers
            NotifyTextMessageEvent tempEvt = new NotifyTextMessageEvent();

            evt.CopyProperties(tempEvt);
            evt = tempEvt;

            evt.Message = evt.Message.Substring(Settings.ChatCommandPrefix.Length);

            bool hasAdmin = Settings.AdminUniqueIds.Contains(evt.InvokerUniqueId);

            if (Parent.RateLimiter.CheckRateLimit("chat_command", evt.InvokerUniqueId, hasAdmin) == false)
            {
                messageCallback.Invoke(ColorCoder.ErrorBright("Slow down a little, you are sending too many commands!"));
                return(true);
            }

            string[]      messageSplit = evt.Message.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            string        command      = messageSplit[0].ToLower();
            List <string> parameters   = messageSplit.Skip(1).ToList();

            parameters = ParseParameterEscapes(parameters);

            ChatCommand commandToExecute = null;

            //Handle exceptions that occur during the parsing of the parameters
            try {
                commandToExecute = GetCommandForMessage(command, parameters, evt.InvokerUniqueId);
            } catch (ChatCommandNotFoundException) {
                messageCallback.Invoke(ColorCoder.ErrorBright("Command was not found"));
                return(true);
            } catch (ChatCommandInvalidSyntaxException ex) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"Invalid syntax. Usage of command:\n{Settings.ChatCommandPrefix}{ex.Message}"));
                return(true);
            } catch (NoPermissionException) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"You don't have access to this command, {ColorCoder.Username(evt.InvokerName)}"));
                return(true);
            } catch (CommandParameterInvalidFormatException ex) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"The {ex.GetParameterPosition()} parameter's format was invalid ({ex.ParameterName} = '{ex.ParameterValue}'). It has to be {ColorCoder.Bold(ex.GetNeededType())}!\nUsage: {Settings.ChatCommandPrefix}{ex.UsageHelp}"));
                return(true);
            } catch (TimeStringParseException ex) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"The provided time value '{ex.Input}' had invalid syntax: {ex.Message}"));
                return(true);
            }


            //Handle exceptions that occur during execution of the command
            try {
                commandToExecute.HandleCommand(evt, command, parameters, messageCallback);
            } catch (MultipleTargetsFoundException ex) {
                string joined = string.Join(", ", ex.AllFoundTargets.Select(client => ColorCoder.Bold($"'{client.Nickname}'")));
                messageCallback.Invoke(ColorCoder.ErrorBright($"Too many targets were found with {ColorCoder.Bold($"'{ex.Message}'")} in their name ({joined})"));
            } catch (CooldownNotExpiredException ex) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"That command is still on cooldown. ({ColorCoder.Bold($"{CooldownManager.FormatCooldownTime(ex.Duration)}")} cooldown)"));
            } catch (NoTargetsFoundException ex) {
                messageCallback.Invoke(ColorCoder.ErrorBright($"No targets were found with {ColorCoder.Bold($"'{ex.Message}'")} in their name..."));
            } catch (Exception ex) {
                Parent.LogMessage($"Encountered exception in command '{commandToExecute.GetType().Name}': {ex}");
            }

            return(true);
        }