public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); // First, substitute the variables. string message = VariableStrings.Replace(command.CommandDetail, args.Username, args.UserId.ToString(), args.GuildName, command.CommandDetail); if (string.IsNullOrWhiteSpace(message)) { // Use the command's name instead. message = command.FullCommandExcludingCommandPrefix; } // Shrug. message = message.StripAccents(); // Now substitute the replacements from the table. StringBuilder sb = new StringBuilder(); foreach (char c in message) { string letter = c.ToString(); foreach (var replacementPair in replaceTable) { letter = letter.Replace(replacementPair.Key, replacementPair.Value, (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); // If a replacement was made. if (letter != c.ToString()) { break; } } sb.Append(letter); } string output = reverse ? new string(sb.ToString().Reverse().ToArray()) : sb.ToString(); List <Response> responses = new List <Response> { new Response { Embed = null, Message = output, ResponseType = ResponseType.Default } }; if (doTTS) { responses.Add( new Response { Embed = null, Message = output, ResponseType = ResponseType.Default_TTS } ); } return(responses.ToArray()); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); return(Response.CreateArrayFromString(AddZalgo(command.CommandDetail))); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { Response response = new Response { Embed = EmbedUtility.ToEmbed(Help), Message = Help, ResponseType = ResponseType.Default }; ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string commandDetail = command.CommandDetail; response = waitHandler.CreatePleaseWaitResponse(senderDetail.ServerSettings.Language); Task.Run(async() => { Response asyncResponse = await BuildMemeAsync(senderDetail.ServerSettings.Language, args); if (asyncResponse == null) { string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoImageMessages")}"); asyncResponse = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; } await asyncResponder.SendResponseAsync(args, asyncResponse); waitHandler.PopPleaseWaitMessage(); }); return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); if (Constants.IsBotOwner(args.UserId)) { Task.Run(async() => { string name = command.CommandDetail; if (args.ChannelId != Constants.ConsoleId) { var guild = await client.GetGuildAsync(args.GuildId).ConfigureAwait(false); var user = guild.GetUser(client.CurrentUser.Id); await user.ModifyAsync(x => x.Nickname = name).ConfigureAwait(false); } else { Console.Title = name; } }); return(new Response[] { Response.CreateFromReact(Emojis.ThumbsUpUnicode) }); } else { return(Response.CreateArrayFromString($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_BotOwnerOnly")}.")); } }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string requestStr = command.CommandDetail; ulong requestedId; if (string.IsNullOrWhiteSpace(requestStr)) { // Default to the user asking. requestedId = args.UserId; } else { // Parse a mention? if (requestStr.StartsWith("<@") && requestStr.EndsWith(">")) { requestStr = requestStr.Substring("<@".Length, requestStr.Length - 3); // Minus 3 for <@nnnnn> } // Id? if (!ulong.TryParse(requestStr, out requestedId)) { // No, fail. return(Response.CreateArrayFromString($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoResults")}: {requestStr}")); } } if (client != null) { Task.Run(async() => { // From the id, determine if it's a user or server. // Is it a server? var candidateServer = await client.GetGuildAsync(requestedId).ConfigureAwait(false); if (candidateServer != null) { await asyncResponder.SendResponseAsync(args, Response.CreateFromString($"{candidateServer.IconUrl}")).ConfigureAwait(false); } // Is it a channel? IChannel candidateChannel = await client.GetDMChannelAsync(requestedId).ConfigureAwait(false); if (candidateChannel != null) { await asyncResponder.SendResponseAsync(args, Response.CreateFromString($"{candidateChannel.GetGuild().IconUrl}")).ConfigureAwait(false); } // Is it a user? IUser candidateUser = client.GetUser(requestedId); if (candidateUser != null) { await asyncResponder.SendResponseAsync(args, Response.CreateFromString($"{candidateUser.GetAvatarUrl(ImageFormat.Auto, 2048)}")).ConfigureAwait(false); } }); } return(new Response[] { Response.WaitForAsync }); }
internal IList <Response> ExecuteCommand(SenderSettings senderDetail, IMessageDetail messageDetail) { List <Response> responses = new List <Response>(); CommandMessageHelper helper = new CommandMessageHelper(senderDetail.ServerSettings.CommandSymbol, messageDetail.Message); Languages currentLanguage = senderDetail.ServerSettings.Language; // If we're running default, assume English. if (currentLanguage == Languages.Default) { currentLanguage = Languages.English; } if (helper.IsCommand || messageDetail.IsPrivate) { // Check language specific commands. foreach (Command command in commands[currentLanguage]) { if (command.Aliases.Contains(helper.CommandLower, StringComparer.OrdinalIgnoreCase) || command.NoSetAlias) { responses.AddRange(command.Execute(senderDetail, messageDetail)); } } // Then check defaults. foreach (Command command in commands[Languages.Default]) { if (command.Aliases.Contains(helper.CommandLower, StringComparer.OrdinalIgnoreCase) || command.NoSetAlias) { responses.AddRange(command.Execute(senderDetail, messageDetail)); } } } else { // Check only commands that do not require a command symbol. // Check language specific commands. foreach (Command command in commands[currentLanguage].Where(c => !c.RequiresSymbol)) { if (command.Aliases.Contains(helper.CommandLower, StringComparer.OrdinalIgnoreCase) || command.NoSetAlias) { responses.AddRange(command.Execute(senderDetail, messageDetail)); } } // Then check defaults. foreach (Command command in commands[Languages.Default].Where(c => !c.RequiresSymbol)) { if (command.Aliases.Contains(helper.CommandLower, StringComparer.OrdinalIgnoreCase) || command.NoSetAlias) { responses.AddRange(command.Execute(senderDetail, messageDetail)); } } } return(responses); }
private async Task <Response> CorrelatePokemonAsync(Languages language, IMessageDetail m) { string[] urls = m.URLs; Response response = null; for (int i = 0; i < urls.Length; i++) { string url = urls[i]; try { // Check if the url is a file if (WebHelper.IsImageUrl(url)) { // It is, download and perform the correlation var tuple = await WebHelper.DownloadFile(url).ConfigureAwait(false); if (tuple.Item2 != null) { response = Response.CreateFromString("URLs not yet supported."); //response = DoCorrelatePokemonAsync(language, tuple.Item2); } else { // We failed, return a response indicating the failure. string err = Emojis.NoEntrySign + " " + tuple.Item1.ReasonPhrase; response = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; } break; } } catch (HttpRequestException ex) { errorLogger.LogDebug($"HttpRequestException exception downloading file: {url}. Assuming file too big.", true); errorLogger.LogException(ex, ErrorSeverity.Information); string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(language, "Error_NotAFile")}"); response = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; break; } catch (Exception ex) { errorLogger.LogDebug($"Exception downloading or handling Pokemon file: {url}", true); errorLogger.LogException(ex, ErrorSeverity.Information); // try other urls } } return(response); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); StringBuilder sb = new StringBuilder(); string charArray = command.CommandDetail.StripAccents(); int length = charArray.Length; if (length > 80) { string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(serverSettings.Language, "Error_NotAFile")}"); sb.AppendLine(err); } else { sb.AppendLine(); foreach (char c in charArray) { if (char.IsLetterOrDigit(c)) { sb.Append(":regional_indicator_").Append(char.ToLowerInvariant(c)).Append(": "); } else if (c == ' ') { sb.Append(":blue_heart: "); } else if (c == '!') { sb.Append(":grey_exclamation: "); } else if (c == '?') { sb.Append(":grey_question: "); } else if (c == '\'') { sb.Append(":arrow_down_small: "); } else { sb.Append(c); } } sb.AppendLine(); foreach (char _ in charArray) { sb.Append(Emojis.CheerleaderSymbols[rand.Next(0, Emojis.CheerleaderSymbols.Count)]).Append(' '); } } return(Response.CreateArrayFromString(sb.ToString())); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { if (Constants.IsBotOwner(senderDetail.UserSettings.UserId)) { controller.Initialise(); return(new Response[] { Response.CreateFromReact(Emojis.SoonUnicode) }); } else { return(Response.CreateArrayFromString($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_BotOwnerOnly")}.")); } }
public async Task SendResponseAsync(IMessageDetail message, Response response) { bool isFromConsole = message is ConsoleMessageDetail; bool isFromSocket = message is SocketMessageWrapper; if (response.ResponseType == ResponseType.None) { // Nothing to do. } else if (isFromConsole || response.ResponseType == ResponseType.LogOnly) { SendMessageToConsole(response); } else { if (isFromSocket) { try { SocketMessageWrapper socketMessageWrapper = (SocketMessageWrapper)message; // If private response, get the DM channel to the user, otherwise use the current channel. IMessageChannel responseChannel = response.ResponseType == ResponseType.Private ? (await socketMessageWrapper.User.GetOrCreateDMChannelAsync()) : (IMessageChannel)socketMessageWrapper.Channel; if (response.ResponseType != ResponseType.Default_React) { SendMessage(response, responseChannel); } else { await socketMessageWrapper.socketMessage.AddReactionAsync(new Emoji(response.Message)).ConfigureAwait(false); } } catch (Exception ex) { ErrorLogger.LogException(ex, ErrorSeverity.Error); ErrorLogger.LogDebug($"Cannot reply to channel {message?.ChannelName} ({message?.ChannelId}) by user {message?.Username} ({message?.UserId}) with response {response?.Message}, Type {response?.ResponseType}, as the message sending threw an exception."); } } else { ErrorLogger.LogError(new Error(ErrorCode.NotImplemented, ErrorSeverity.Error, $"Cannot reply to channel {message.ChannelName} ({message.ChannelId}) by user {message.Username} ({message.UserId}) as the message is not from the socket.")); } } }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string responseMessage; if (Constants.IsBotOwner(args.UserId)) { string channelIdStr = command.CommandParams[1]; if (!string.IsNullOrWhiteSpace(channelIdStr)) { bool parsed = ulong.TryParse(channelIdStr, out ulong targetChannelId); if (parsed) { string messageToSend = string.Join(" ", command.CommandParams, 2, command.CommandParams.Length - 2); if (string.IsNullOrEmpty(messageToSend)) { responseMessage = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_IncorrectParameter")}: say <channel id> <message> -- message"); } else { if (asyncResponder.SendResponse(targetChannelId, Response.CreateFromString(messageToSend))) { responseMessage = ($"{Emojis.TickSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "YourRequestHasBeenSent")}: {messageToSend} --> {channelIdStr}"); } else { responseMessage = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoResults")}: {channelIdStr}"); } } } else { responseMessage = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_IncorrectParameter")}: say <channel id> <message> -- {channelIdStr}"); } } else { responseMessage = $"{Emojis.CrossSymbol} say <channel id> <message>."; } } else { responseMessage = $"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_BotOwnerOnly")}."; } return(Response.CreateArrayFromString(responseMessage)); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { StringBuilder retVal = new StringBuilder(); ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string[] commandParams = command.CommandParams; Command[] commands = commandController.GetCommandsForLanguage(senderDetail.ServerSettings.Language); Discord.Color responseColor = Discord.Color.Green; if (string.IsNullOrWhiteSpace(command.CommandDetail)) { var commandsByModule = commands.GroupBy(x => x.Module).ToDictionary(grouping => grouping.Key, grouping => grouping.ToList()); foreach (var pair in commandsByModule) { retVal.Append("**"); retVal.Append(pair.Key.ToString()); retVal.AppendLine("**"); retVal.AppendLine(string.Join(", ", pair.Value.Select(c => c.Aliases[0]))); retVal.AppendLine(); } } else { string search = command.CommandArgs.First().ToLowerInvariant(); Command found = commands.FirstOrDefault(c => c.Aliases.Contains(search, StringComparer.OrdinalIgnoreCase)); if (found != null) { retVal.AppendLine(found.Help + "\r\n" + found.Examples); } else { retVal.AppendLine($"{Emojis.QuestionSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_IncorrectParameter")}"); responseColor = Discord.Color.Red; } } string message = retVal.ToString(); Response response = new Response { Embed = Utility.EmbedUtility.ToEmbed(message, responseColor), Message = message, ResponseType = ResponseType.Default }; return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string choice = choices[rand.Next(choices.Length)]; string result = VariableStrings.Replace(choice, args.Username, args.UserId.ToString(), args.GuildName, command.CommandDetail); Response response = new Response { Embed = null, Message = result, ResponseType = responseType }; return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; UserSettings userSettings = senderDetail.UserSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string[] commandParams = command.CommandParams; var allAchievements = SaveData.Achievements.Achievement.AllAchievements; var unlockedAchievements = userSettings.UserStats.GetAchievements(); // First, reply to the room that the command was written in. // This has minimal information so as to not spoil achievements // for other users. string outputToChannel = ($"{languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Achievements_AchievementsUnlocked")}: {unlockedAchievements.Count}/{allAchievements.Count} {Emojis.Trophy}"); Response channelResponse = new Response { Embed = Utility.EmbedUtility.ToEmbed(outputToChannel, 200, 200, 50), ResponseType = ResponseType.Default }; // Next, PM the user their achievements and any still to unlock. StringBuilder sb = new StringBuilder(); foreach (var achievement in allAchievements) { if (achievement.HasAchieved(userSettings.UserStats)) { sb.AppendLine($"{Emojis.Trophy} {achievement.GetDescription(languageHandler, senderDetail.ServerSettings.Language)}"); } else { sb.AppendLine($"???"); } } string outputToPrivate = sb.ToString(); Response privateResponse = new Response { Embed = Utility.EmbedUtility.ToEmbed(outputToPrivate, 200, 200, 50), ResponseType = ResponseType.Private }; return(new[] { channelResponse, privateResponse }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { StringBuilder sb = new StringBuilder(); ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string commandDetail = command.CommandDetail; // Split by or delimiter, not space. if (command.FullCommandExcludingCommandPrefix.ToLowerInvariant().Contains(delimiter)) { string[] orChoices = commandDetail.Split(delimiter); if (!orChoices.Any()) { sb.AppendLine($"{command.CommandSymbol}{command.CommandLower} A{delimiter}B{delimiter}C..."); } else { sb.AppendLine(orChoices[rand.Next(orChoices.Length)].Trim()); sb.Append("_").Append(languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "IgnoredOr")).Append("_"); } } // Else split by space else { string[] choices = command.CommandArgs.ToArray(); if (!choices.Any()) { sb.AppendLine($"{command.CommandSymbol}{command.CommandLower} A B C ..."); } else { sb.AppendLine(choices[rand.Next(choices.Length)]); } } return(Response.CreateArrayFromString(sb.ToString())); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); StringBuilder choice = new StringBuilder(choiceFormat); for (int i = 0; i < choices.Length; i++) { choice.Replace($"{{{i}}}", choices[i][rand.Next(choices[i].Length)]); } string result = VariableStrings.Replace(choice, args.Username, args.UserId.ToString(), args.GuildName, command.CommandDetail).ToString(); Response response = new Response { Embed = null, Message = result, ResponseType = responseType }; return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { // Responds asynchronously. Task.Run(async() => { JContainer json; string message = null; try { json = (JContainer)await JSONHelper.GetJsonAsync(url); } catch (Exception) { json = null; message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_ServerNotFound")}"); } string file = null; if (json != null) { file = formattedResponseURL.Replace("%file%", json[jsonProperty].ToString()); message = file; } Response asyncResponse = new Response { ResponseType = ResponseType.Default, Embed = (file == null) ? null : EmbedUtility.ToEmbed(imageURL: file), Message = message }; await asyncResponder.SendResponseAsync(args, asyncResponse); }); // Return out the lifecycle with no response. return(new[] { Response.WaitForAsync }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string[] commandParams = command.CommandParams; if (Constants.IsBotOwner(args.UserId)) { var servers = (client.Guilds).ToArray(); string serverOutputString = string.Join("\n ", servers.Select((server) => { var ss = serverSettingsHandler.GetOrCreateServerSettings(server.Id); var owner = server.Owner; return($"`{server.Name}` ({ss.Language}): `{owner?.Username}`"); })); return(Response.CreateArrayFromString(servers.Length + " servers: \n" + serverOutputString)); } return(Response.CreateArrayFromString($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, "Error_BotOwnerOnly")}.")); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); Discord.Color responseColor; string message; if (ImageManipulator.FindHexColour(command.CommandDetail, out string foundColour)) { var color = ImageManipulator.FromHexCode(foundColour); responseColor = new Discord.Color(color.R, color.G, color.B); var knownColor = color.ToKnownColor(); message = knownColor != 0 ? $"✓ {knownColor}" : $"(~) {color.ToConsoleColor()}"; } else if (Enum.TryParse(command.CommandDetail, true, out KnownColor knownColor)) { var color = Color.FromKnownColor(knownColor); responseColor = new Discord.Color(color.R, color.G, color.B); message = $"✓ {knownColor}"; } else { responseColor = Discord.Color.Default; message = $"{Emojis.QuestionSymbol} {command.CommandDetail}"; } Response response = new Response { Embed = Utility.EmbedUtility.ToEmbed(message, responseColor), Message = message, ResponseType = ResponseType.Default }; return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CultureInfo cultureInfo = languageHandler.GetCultureInfo(serverSettings.Language); CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); Discord.Color responseColor = Discord.Color.Green; // First, check the cache if we already have this pokémon. string query = command.CommandDetail; if (args.URLs.Length > 0) { var response = new[] { waitHandler.CreatePleaseWaitResponse(senderDetail.ServerSettings.Language) }; Task.Run(async() => { Response asyncResponse = await CorrelatePokemonAsync(senderDetail.ServerSettings.Language, args); if (asyncResponse == null) { string err = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoImageMessages")}"); asyncResponse = new Response { Embed = EmbedUtility.ToEmbed(err), Message = err, ResponseType = ResponseType.Default }; } await asyncResponder.SendResponseAsync(args, asyncResponse); waitHandler.PopPleaseWaitMessage(); }); return(response); } query = query.Replace("(Pokemon)", "").Replace("(Pokémon)", "").Trim(); query = query.Replace("(move)", "").Trim(); StringBuilder output = new StringBuilder(); Pokemon pokemon = KnowledgeBase.GetPokémon(query); string imageUrl = null; bool isCached = (pokemon != null); try { // For now, assume that it is a Pokémon. string url = "https://bulbapedia.bulbagarden.net/wiki/" + query.Capitalize() + "_(Pokémon)"; string urlRaw = url + "?action=raw"; if (!isCached) { // Assume correct URL pokemon = Pokemon.ParsePage(urlRaw); } if (pokemon != null) { string p = pokemon.Name + "_(Pokémon)"; dynamic imageJson = null; output .Append("https://bulbapedia.bulbagarden.net/wiki/") .Append(p) .AppendLine("#") // # is for mobile where () is not correctly parsed in the URL parser .AppendLine(MakeAPokemonString(pokemon, cultureInfo, serverSettings.Language)); try { cancellationTokenSource.CancelAfter(300000); Task.Run(async() => { imageJson = await JSONHelper.GetJsonAsync(Uri.EscapeUriString("https://bulbapedia.bulbagarden.net/w/api.php?action=query&format=json&prop=pageimages&titles=" + p)).ConfigureAwait(false); }, cancellationTokenSource.Token).Wait(); JToken token = imageJson["query"]["pages"]; token = token.First.First; imageUrl = token["thumbnail"]["source"]?.ToString(); } catch (TaskCanceledException tcex) { errorLogger.LogDebug("Did not query Bulbapedia in time to retrieve the Pokemon image.", true); errorLogger.LogException(tcex, ErrorSeverity.Warning); } catch (Exception ex) { errorLogger.LogDebug($"Exception occurred retrieving the Pokemon image for {pokemon?.Name}.\n" + $"imageUrl: {imageUrl}\n" + $"imageJson: {imageJson}", true); errorLogger.LogException(ex, ErrorSeverity.Error); } } else { output.AppendLine($"{Emojis.ExclamationSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_PokemonNotFound")}: {urlRaw}"); } } catch (WebException) { output.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_PokemonNotFound")}: {query}"); } catch (Exception ex) { output.AppendLine($"{languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops")}: {ex.Message}"); } return(Response.CreateArrayFromString(output.ToString(), responseColor, pokemon.Name, imageUrl)); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { string retVal = ""; ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string[] commandParams = command.CommandParams; ushort flips; Discord.Color responseColor = new Discord.Color(0); if (commandParams.Length == 1) { flips = 1; } else { if (!ushort.TryParse(commandParams[1], out flips) || flips <= 0) { retVal = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, Errors.ErrorCode.IncorrectParameter)}: {commandParams[1]}. [1-{uint.MaxValue}]."); } } if (flips > 0) { int heads = 0, tails = 0; string localeHead = languageHandler.GetPhrase(serverSettings.Language, "CoinHead"); string localeTail = languageHandler.GetPhrase(serverSettings.Language, "CoinTail"); if (flips == 1) { switch (rand.Next(2)) { default: case 0: retVal = localeHead; heads++; break; case 1: retVal = localeTail; tails++; break; } } else { char headLetter = (localeHead)[0]; char tailLetter = (localeTail)[0]; string flipped = languageHandler.GetPhrase(serverSettings.Language, "Flipped"); if (flips > 100) { for (int i = 0; i < flips; i++) { switch (rand.Next(2)) { case 0: heads++; break; case 1: tails++; break; } } retVal = ($"{flipped} {flips}x, `{localeHead}:` {heads}, `{localeTail}:` {tails}"); } else { StringBuilder coinflips = new StringBuilder(); for (int i = 0; i < flips; i++) { switch (rand.Next(2)) { case 0: coinflips.Append(headLetter); heads++; break; case 1: coinflips.Append(tailLetter); tails++; break; } } retVal = ($"{flipped} {flips}x, `{localeHead}:` {heads}, `{localeTail}:` {tails}: {coinflips.ToString()}"); } } if (heads < tails) { responseColor = new Discord.Color(200, 50, 50); } else if (heads > tails) { responseColor = new Discord.Color(50, 200, 50); } else { responseColor = new Discord.Color(200, 200, 50); } } Response response = new Response { Embed = Utility.EmbedUtility.ToEmbed(retVal, responseColor), Message = retVal, ResponseType = ResponseType.Default }; return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { StringBuilder output = new StringBuilder(); ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string[] commandParams = command.CommandParams; long min = 0; long max; if (commandParams.Length == 1) { max = 10; } else if (commandParams.Length == 2) { if (!long.TryParse(commandParams[1], NumberStyles.Any, CultureInfo.InvariantCulture, out max)) { if (commandParams[1] == "∞" || commandParams[1].StartsWith("inf")) { max = long.MaxValue; } else if (commandParams[1] == "-∞" || commandParams[1].StartsWith("-inf")) { max = long.MinValue; } else { output.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, Errors.ErrorCode.IncorrectParameter)}: {commandParams[1]}."); max = 10; } } } else { if (!long.TryParse(commandParams[1], NumberStyles.Any, CultureInfo.InvariantCulture, out min)) { if (commandParams[1] == "∞" || commandParams[1].StartsWith("inf")) { min = long.MaxValue; } else if (commandParams[1] == "-∞" || commandParams[1].StartsWith("-inf")) { min = long.MinValue; } else { output.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, Errors.ErrorCode.IncorrectParameter)}: {commandParams[1]}."); min = 0; } } if (!long.TryParse(commandParams[2], NumberStyles.Any, CultureInfo.InvariantCulture, out max)) { if (commandParams[2] == "∞" || commandParams[2].StartsWith("inf")) { max = long.MaxValue; } else if (commandParams[2] == "-∞" || commandParams[2].StartsWith("-inf")) { max = long.MinValue; } else { output.AppendLine($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(serverSettings.Language, Errors.ErrorCode.IncorrectParameter)}: {commandParams[2]}."); max = 10; } } } if (min > max) { // Swap long temp = max; max = min; min = temp; } long num = rand.NextLong(min, max == long.MaxValue ? long.MaxValue : max + 1); output.AppendLine((min) + " -> " + (max) + ": " + num); ulong range = (ulong)(max - min); if (range == 0) { range = 1; } long normNum = (num - min); float percentage = (((float)normNum) / range) * 360; if (percentage > 360) { percentage = 360; } var drawingColour = Imaging.ImageManipulator.FromAHSB(255, percentage, 0.8f, 0.5f); var responseColor = new Discord.Color(drawingColour.R, drawingColour.G, drawingColour.B); string retVal = output.ToString(); Response response = new Response { Embed = Utility.EmbedUtility.ToEmbed(retVal, responseColor), Message = retVal, ResponseType = ResponseType.Default }; return(new[] { response }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { UserSettings userSettings = senderDetail.UserSettings; // If the message has a file and was sent to us in private, save that file. if (Constants.IsBotOwner(userSettings.UserId) && args is SocketMessageWrapper socketMessage && socketMessage.IsPrivate && socketMessage.socketMessage is SocketUserMessage socketUserMessage) { if (socketUserMessage.Attachments.Count > 0 || socketUserMessage.Embeds.Count > 0) { Task.Run(async() => { List <string> receivedFiles = new List <string>(); foreach (var attachment in socketUserMessage.Attachments) { var result = await WebHelper.DownloadFile(attachment.Url).ConfigureAwait(false); if (result?.Item2 != null) { string path = Path.Combine(dal.receivedFilesFolder, attachment.Filename); await File.WriteAllBytesAsync(path, result.Item2).ConfigureAwait(false); receivedFiles.Add(path); } } foreach (var embed in socketUserMessage.Embeds) { if (embed.Image.HasValue) { var image = (EmbedImage)embed.Image; var result = await WebHelper.DownloadFile(image.Url).ConfigureAwait(false); if (result?.Item2 != null) { string path = Path.Combine(dal.receivedFilesFolder, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff")); await File.WriteAllBytesAsync(path, result.Item2).ConfigureAwait(false); receivedFiles.Add(path); } } } try { // If sent with no command, scan the file if it's an xml // to check if the file is a new command. if (string.IsNullOrWhiteSpace(args.Message)) { var commandFiles = receivedFiles.Select(file => dal.LoadCopySingleCommand(file)); if (commandFiles.Any(f => f != null)) { // Reinitialise the command controller to ensure the new files are accepted. commandController.Initialise(); await asyncResponder.SendResponseAsync(args, Response.CreateFromString("Reinitialising the commands.")).ConfigureAwait(false); } await asyncResponder.SendResponseAsync(args, Response.CreateFromReact(Emojis.DiscUnicode)).ConfigureAwait(false); } // Otherwise if sent with an update command, overwrite the program file else if (args.Message.Equals("update", StringComparison.OrdinalIgnoreCase) || args.Message.Equals(Emojis.DiscUnicode)) { foreach (var received in receivedFiles) { string fileName = Path.GetFileName(received); string destination = Path.Combine(dal.programFolder, fileName); if (File.Exists(destination)) { File.Move(destination, Path.Combine(dal.programFolderOld, fileName), true); } File.Copy(received, destination); } } } catch (Exception ex) { dal.errorLogger.LogException(ex, Errors.ErrorSeverity.Error); dal.errorLogger.LogDebug("Error occurred in receiving file for update/transfer."); } }); return(new Response[] { Response.WaitForAsync }); } } return(Response.NoResponse); }
/// <summary> /// Handle a command received from chat. /// This is after filtering to make sure a message is a command. /// </summary> internal void HandleCommandReceived(SenderSettings senderSettings, IMessageDetail message) { bool success; IList <Response> responses; try { responses = commandHandlerController.ExecuteCommand(senderSettings, message); success = true; } catch (Exception ex) { ErrorLogger.LogException(ex, ErrorSeverity.Error); ErrorLogger.LogDebug($"Exception while handling: {message}", false); responses = new List <Response> { new Response { Message = $"{Emojis.ExclamationSymbol} {languageHandler.GetPhrase(senderSettings.ServerSettings.Language, "Error_Oops")}: {ex.Message}" } }; success = false; } if (dumpDebug) { var sb = MiscUtility.DumpObject(message); ErrorLogger.LogDebug("Handled " + message.GetType() + ": \r\n" + sb, true); } if (responses.Count > 0) { foreach (Response response in responses) { OnCommandReceived?.Invoke(this, new CommandReceivedEventArgs(senderSettings, message, response)); /// Handled by <see cref="SlateBotController_OnCommandReceived"/> /// and the <see cref="UserSettingsHandler"/> if (dumpDebug) { var sb = MiscUtility.DumpObject(response); ErrorLogger.LogDebug("Response " + response.GetType() + ": \r\n" + sb, true); } } if ((message is SocketMessageWrapper smw) && (smw.socketMessage is SocketUserMessage sum)) { // Help out if we're debugging. if (Debugger.IsAttached) { var sb = MiscUtility.DumpObject(sum); ErrorLogger.LogDebug("Handled " + sum.GetType() + ": \r\n" + sb, dumpDebug); } // React to the message handled. sum.AddReactionAsync(new Emoji(success ? Emojis.CheckUnicode : Emojis.CrossSymbol)).ConfigureAwait(false); } } else if (message is ConsoleMessageDetail) // If from the console { ErrorLogger.LogDebug(NO_RESPONSE_CONSOLE_MESSAGE + "(" + message.Message + ")", true); } }
/// <summary> /// Handle an incoming command and return response object(s) as a result. /// The result may not be null. Empty indicates unhandled. A response can be of <see cref="ResponseType.None"/> for a handled silent response. /// </summary> /// <param name="sender">Settings context</param> /// <param name="args">Message context</param> /// <returns>The response objects to reply with.</returns> public abstract IList <Response> Execute(SenderSettings sender, IMessageDetail args);
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CultureInfo cultureInfo = languageHandler.GetCultureInfo(serverSettings.Language); CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string[] commandParams = command.CommandParams; Discord.Color responseColor = Discord.Color.Green; string[] typeStrings; if (command.CommandDetail.Contains('-')) { // User wrote e.g. normal-flying typeStrings = command.CommandDetail.Split('-'); } else { typeStrings = command.CommandArgs.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); } if (typeStrings.Length == 0) { // No types specified. return(Response.CreateArrayFromString("http://bulbapedia.bulbagarden.net/wiki/Type")); } List <string> incorrectTypes = new List <string>(); List <string> duplicateTypes = new List <string>(); var foundTypes = new HashSet <PokemonType>(); // TODO - translate. if (typeStrings.Length == 1 && typeStrings[0].Equals("all", StringComparison.OrdinalIgnoreCase)) { // Add all types. foreach (PokemonType t in PokemonTypeHandler.PokemonTypes) { if (t != PokemonType.NumberOfTypes) { foundTypes.Add(t); } } } else { foreach (string typeStr in typeStrings) { bool found = PokemonTypeHandler.GetTypeFromLocalisedName(typeStr, cultureInfo, out PokemonType t); if (found) { bool added = foundTypes.Add(t); if (!added) { duplicateTypes.Add(typeStr); } } else { incorrectTypes.Add(typeStr); } } } bool foundAny = foundTypes.Any(); if (!foundAny) { // Check if is actually a Pokémon. Pokemon pokemon = (KnowledgeBase.GetOrFetchPokémon(command.CommandDetail)); if (pokemon != null) { foundTypes.Add(pokemon.PrimaryType); if (pokemon.SecondaryType != PokemonType.NumberOfTypes) { foundTypes.Add(pokemon.SecondaryType); } foundAny = true; // Ignore the typing - it's a Pokémon. incorrectTypes.Clear(); duplicateTypes.Clear(); } } StringBuilder sb = new StringBuilder(); // Incorrect types if (incorrectTypes.Any()) { sb.Append($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_IncorrectParameter")}"); sb.Append(": "); sb.AppendLine(string.Join(" ", incorrectTypes)); } // Duplicate types if (duplicateTypes.Any()) { sb.Append($"{Emojis.ExclamationSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Warning_SameType")}"); sb.Append(": "); sb.AppendLine(string.Join(" ", duplicateTypes)); } if (foundAny) { sb.AppendLine("```objectivec"); sb.Append("// "); foreach (PokemonType foundType in foundTypes) { string foundTypeName = PokemonTypeHandler.GetLocalisedName(foundType, cultureInfo); sb.Append(foundTypeName); sb.Append(" "); } sb.AppendLine(); // Attacking if (foundTypes.Count < 3) { sb.AppendLine($"# {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Attacking")}"); foreach (PokemonType foundType in foundTypes) { double[] attackingType1 = PokemonTypeHandler.GetAttacking(foundType); for (int i = 0; i < attackingType1.Length; i++) { double eff = attackingType1[i]; if (eff != 1.0) { sb.Append(eff.ToString("G", cultureInfo.NumberFormat)); sb.Append($"x {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Against")} "); sb.Append(PokemonTypeHandler.GetLocalisedName(PokemonTypeHandler.PokemonTypes[i], cultureInfo)); sb.Append($" {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "WhenAttackingWith")} "); sb.Append(PokemonTypeHandler.GetLocalisedName(foundType, cultureInfo)); sb.AppendLine(); } } } } sb.AppendLine(); // Defending sb.AppendLine($"# {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Defending")}"); double[] defending = PokemonTypeHandler.GetDefending(foundTypes.ToArray()); for (int i = 0; i < defending.Length; i++) { double eff = defending[i]; if (eff != 1.0) { sb.Append(eff.ToString("G", cultureInfo.NumberFormat)); sb.Append($"x {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "DamageTakenFrom")} "); sb.AppendLine(PokemonTypeHandler.GetLocalisedName(PokemonTypeHandler.PokemonTypes[i], cultureInfo)); } } // Add on status immunities. foreach (PokemonType foundType in foundTypes) { string immunity = PokemonTypeHandler.GetTypeStatusImmunityString(foundType, cultureInfo); if (immunity != string.Empty) { sb.AppendLine(immunity); } } sb.Append("```"); } return(Response.CreateArrayFromString(sb.ToString(), responseColor)); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string query = command.CommandDetail; // Responds asynchronously. Task.Run(async() => { JContainer json; string message = null; string weapon = Splatoon.SplatoonDefs.TryFindWeapon(query); if (weapon != null) { try { string buildsQuery = $@"query {{ searchForBuilds(weapon: ""{weapon}"") {{ headgear clothing shoes }} }}"; string builtUrl = $"{url}?query={Uri.EscapeUriString(buildsQuery)}"; json = (JContainer)JsonConvert.DeserializeObject(await RequestsHelper.CurlGetCommand(builtUrl, origin).ConfigureAwait(false)); } catch (Exception ex) { json = null; message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_ServerNotFound")}"); Console.WriteLine(ex); } try { dynamic jsonResult = json["data"]["searchForBuilds"]; int count = 0; foreach (var node in jsonResult) { JArray headgear = node["headgear"]; JArray clothing = node["clothing"]; JArray shoes = node["shoes"]; string[] mains = new string[] { headgear[0].ToString(), clothing[0].ToString(), shoes[0].ToString() }; List <string> subs = new List <string>(); subs.AddRange(headgear.Skip <JToken>(1).Values <string>()); subs.AddRange(clothing.Skip <JToken>(1).Values <string>()); subs.AddRange(shoes.Skip <JToken>(1).Values <string>()); var mainsDict = new Dictionary <string, int>(mains.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count()).OrderByDescending(pair => pair.Value)); var subsDict = new Dictionary <string, int>(subs.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count()).OrderByDescending(pair => pair.Value)); StringBuilder sb = new StringBuilder(); foreach (var pair in mainsDict) { sb.Append(pair.Value).Append("m"); if (subsDict.ContainsKey(pair.Key)) { sb.Append(pair.Value).Append("s"); subsDict.Remove(pair.Key); } sb.Append(" ").Append(pair.Key).Append(", "); } foreach (var pair in subsDict) { sb.Append(pair.Value).Append("s"); sb.Append(" ").Append(pair.Key).Append(", "); } sb.AppendLine(); message += sb.ToString(); count++; if (count > 6) { break; } } } catch (Exception ex) { message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops")}"); Console.WriteLine(ex); } } else { message = ($"{Emojis.QuestionSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoResults")}"); } Response asyncResponse = new Response { ResponseType = ResponseType.Default, Embed = EmbedUtility.ToEmbed(message, null), Message = message }; await asyncResponder.SendResponseAsync(args, asyncResponse); }); // Return out the lifecycle with no response. return(new[] { Response.WaitForAsync }); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); // Verify command. string[] splitCommand = command.CommandLower.Split('>', StringSplitOptions.RemoveEmptyEntries); if (splitCommand.Length == 2) { var sourceLanguage = splitCommand[0]; if (!translateCodes.Contains(sourceLanguage)) { if (string.Equals(sourceLanguage, "?") || sourceLanguage.Equals("auto", StringComparison.OrdinalIgnoreCase)) { sourceLanguage = "auto"; } else { // If the source language is not found, then assume the command is not for us. return(Response.NoResponse); } } // Command verified, continue with the translation. var targetLanguage = splitCommand[1]; var toTranslate = command.CommandDetail; if (string.IsNullOrWhiteSpace(toTranslate)) { return(Response.CreateArrayFromString(TRANSLATE_HOMEPAGE)); } else if (!translateCodes.Contains(targetLanguage)) { string err = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_IncorrectParameter")}: {targetLanguage}"); return(Response.CreateArrayFromString(err)); } string query = Uri.EscapeDataString(toTranslate); string request = "https://translate.googleapis.com/translate_a/single?client=gtx&dt=t" + $"&ie=UTF-8" + $"&oe=UTF-8" + $"&sl={sourceLanguage}" + $"&tl={targetLanguage}" + $"&q={query}"; errorLogger.LogDebug(request, false); // Responds asynchronously. Task.Run(async() => { JContainer json; string message = null; try { json = (JContainer)await JSONHelper.GetJsonAsync(request).ConfigureAwait(false); } catch (Exception) { json = null; message = ($"{Emojis.NoEntry} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_ServerNotFound")}"); } try { dynamic outer = json[0]; if (outer.Count > 0) { StringBuilder translation = new StringBuilder(); for (int i = 0; i < outer.Count; i++) { string translatedLine = outer[i][0]?.ToString(); if (translatedLine != null) { translation.AppendLine(translatedLine); } } if (translation.Length <= 0) { message = ($"{Emojis.Warning} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoResults")}"); } else { message = translation.ToString(); } } else { message = ($"{Emojis.Warning} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_NoResults")}"); } } catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex) { // Extra information for debugging. errorLogger.LogException(ex, ErrorSeverity.Error); errorLogger.LogDebug("Unable to process the translation response: " + ex, true); errorLogger.LogDebug("Request: " + request, true); errorLogger.LogDebug("Response: " + json, true); // Let the usual error handling kick in. throw; } Response asyncResponse = Response.CreateFromString(message); await asyncResponder.SendResponseAsync(args, asyncResponse).ConfigureAwait(false); }); // Return out the lifecycle with no response. return(new[] { Response.WaitForAsync }); } else { return(Response.NoResponse); } }
public CommandReceivedEventArgs(SenderSettings senderDetail, IMessageDetail message, Response response) { this.senderSettings = senderDetail ?? throw new ArgumentNullException(nameof(senderDetail)); this.message = message ?? throw new ArgumentNullException(nameof(message)); this.response = response ?? throw new ArgumentNullException(nameof(response)); }
public override IList <Response> Execute(SenderSettings senderDetail, IMessageDetail args) { ServerSettings serverSettings = senderDetail.ServerSettings; CommandMessageHelper command = new CommandMessageHelper(serverSettings.CommandSymbol, args.Message); string query = command.CommandDetail; StringBuilder output = new StringBuilder(); try { const string url = "https://wiki.teamfortress.com/wiki/Crafting"; const string urlRaw = url + "?action=raw"; if (cachedText == null) { cachedText = WebHelper.GetText(urlRaw); } string rawText = cachedText; // First we need to decide on what we're searching for. bool multiLookup = (!query.Contains("Fabricate", StringComparison.OrdinalIgnoreCase) && !query.Contains("Smelt", StringComparison.OrdinalIgnoreCase) && !query.Contains("Combine", StringComparison.OrdinalIgnoreCase)); if (multiLookup) { query = "Fabricate " + query; } bool querySatisfied = rawText.ContainsIgnore(query, StringComparison.OrdinalIgnoreCase, " ", "_", "-", "."); if (!querySatisfied && multiLookup) { query = "Smelt " + query; querySatisfied = rawText.ContainsIgnore(query, StringComparison.OrdinalIgnoreCase, " ", "_", "-", "."); } if (!querySatisfied && multiLookup) { query = "Combine " + query; querySatisfied = rawText.ContainsIgnore(query, StringComparison.OrdinalIgnoreCase, " ", "_", "-", "."); } if (!querySatisfied) { string error = ($"{Emojis.ExclamationSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_UnknownRecipe")}"); output.AppendLine(error + " " + query + ": " + url); } else { // We're in business. TextParser parser = new TextParser(rawText); parser.MovePast(query, true); parser.MovePast("|", true); // First parameter is blueprint name string recipeTemplate = parser.ExtractUntil("bprow", false, true); if (string.IsNullOrEmpty(recipeTemplate)) { // Go to the end of the table instead. recipeTemplate = parser.ExtractUntil("</", false, true); } recipeTemplate = recipeTemplate.Replace("{{Item icon|", "").Replace("'''", "").Replace("''", "").Replace("{", "").Replace("}", "").Replace("\r", "").Replace("\n", "").Replace("\\r", "").Replace("\\n", "").Replace(" ", " ").Replace("<small>", " ").Replace("</small>", " ").Replace("=", "").Replace("×", "x").Replace("→", "→").Trim('|', ' '); string[] templateArgs = recipeTemplate.Split('|'); if (templateArgs.Length < 2) { string error = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops")}"); output.Append(error).Append(' ').Append(query).Append(": ").AppendLine(url); } else { output.AppendLine("`Requirements: " + templateArgs[0].Trim() + "`"); output.AppendLine("`Produces: " + templateArgs[1].Trim() + "`"); for (int i = 2; i < templateArgs.Length; i++) { if (templateArgs[i].Contains("cost") || i == templateArgs.Length - 1) { string costStr = templateArgs[i].Replace("cost", ""); if (costStr.Contains("</")) { costStr = (costStr.Substring(0, costStr.IndexOf("</"))); } output.AppendLine("`Cost: " + costStr.Trim() + " weapon units.`"); break; } else { output.AppendLine("`" + templateArgs[i].Trim() + "`"); } } } } } catch (Exception ex) { string error = ($"{Emojis.CrossSymbol} {languageHandler.GetPhrase(senderDetail.ServerSettings.Language, "Error_Oops")}"); output.AppendLine(error + " " + query + " " + ex.Message); } return(Response.CreateArrayFromString(output.ToString())); }