public string ViewOption(string optionId, bool allowTooltips = true) { PropertyInfo option = ClassHelper.GetProperty(this, optionId); if (option == null) { return(Format.Warning("Unknown option specified.")); } return(ViewOption(option, allowTooltips)); }
public async Task ViewChangelogAsync() { IChannel channel = Context.Client.GetChannel(Context.Data.Data.LogChannelId); if (channel is IMessageChannel mChannel) { IEnumerable <IMessage> messages = await mChannel.GetMessagesAsync(1).FlattenAsync(); IMessage message = messages.FirstOrDefault(); if (message != null) { await message.CloneAsync(Context.Channel); return; } } await Context.Channel.SendMessageAsync(Format.Warning("Unable to find a previous changelog to reference.")); }
public async Task SetOptionAsync(string name, [Name("value")] string unparsed) { PropertyInfo option = ClassHelper.GetProperty(Context.Account.Config, name); if (option == null) { await Context.Channel.SendMessageAsync(Format.Warning("Unknown option specified.")); return; } Type type = Context.Account.Config.GetOptionType(name); var clamp = option.GetCustomAttribute <ClampAttribute>(); bool useFlags = type.GetCustomAttribute <FlagsAttribute>() != null; var panel = new StringBuilder(); panel.AppendLine($"> **{Context.Account.Config.GetOptionName(name)}**"); switch (unparsed) { case "--default": Context.Account.Config.SetOptionDefault(name); panel.AppendLine("> The specified option has been reset."); break; case "--min": { if (type != typeof(int)) { panel.AppendLine("> This method can only be used on a `Number` with a specified minimum range."); } else if (clamp == null || !clamp.HasMin) { panel.AppendLine("> This `Number` does not have a specified minimum range."); } else { Context.Account.Config.SetOption(name, clamp.Min); panel.AppendLine("> The specified option has been set to its lowest possible value."); } break; } case "--max": { if (type != typeof(int)) { panel.AppendLine("> This method can only be used on a `Number` with a specified maximum range."); } else if (clamp == null) { panel.AppendLine("> This `Number` does not have a specified maximum range."); } else { Context.Account.Config.SetOption(name, clamp.Max); panel.AppendLine("> The specified option has been set to its highest possible value."); } break; } case "--none": { if (!type.IsEnum || !useFlags) { panel.AppendLine("> This method can only be used on a `Flag`."); } else if (!Enum.TryParse(type, "0", out object e)) { panel.AppendLine("> An error occurred while attempted to clear all flags."); } else { Context.Account.Config.SetOption(name, e); panel.AppendLine("> Cleared all flags."); } break; } case "--all": { if (!type.IsEnum || !useFlags) { panel.AppendLine("> This method can only be used on a `Flag`."); } else if (!Enum.TryParse(type, $"{type.GetEnumValues().Cast<Enum>().Select(Convert.ToInt64).Sum()}", out object e)) { panel.AppendLine("> An error occurred while attempting to activate all flags."); } else { Context.Account.Config.SetOption(name, e); panel.AppendLine("> Activated all flags."); } break; } default: if (TypeParser.TryParse(type, unparsed, out object result)) { if (type.IsEnum) { long flagValue = Convert.ToInt64(result); if (flagValue < 0) { panel.AppendLine("> Flags cannot be negative."); break; } long partialSum = EnumUtils.GetFlags(result).Select(Convert.ToInt64).Sum(); if (flagValue > 0) { if (flagValue - partialSum > 0) { panel.AppendLine("> The flag summation contains an invalid flag."); break; } } } if (type == typeof(string) && result is string s) { if (s.Contains("\n")) { panel.AppendLine("> The specified value cannot contain any line breaks."); break; } if (clamp != null) { if (s.Length > clamp.Max) { panel.AppendLine($"> The specified value cannot be larger than `{clamp.Max}`."); break; } } } if (type == typeof(int) && result is int i) { if (clamp != null) { if (clamp.HasMin && (i < clamp.Min || i > clamp.Max)) { panel.AppendLine($"> The specified value is out of range (`{clamp.Min} to {clamp.Max}`)."); break; } if (i > clamp.Max) { panel.AppendLine($"> The specified value cannot be larger than `{clamp.Max}`."); break; } } } Context.Account.Config.SetOption(name, result); panel.Append($"> The specified value has been set to `{Context.Account.Config.WriteOptionValue(result)}`."); } else { panel.AppendLine("> The specified value could not be parsed."); if (type.IsEnum) { panel.AppendLine(); List <string> names = type.GetEnumNames().ToList(); List <long> values = type.GetEnumValues().Cast <object>().Select(Convert.ToInt64).ToList(); List <string> groups = names.Join(values, a => names.IndexOf(a), b => values.IndexOf(b), (a, b) => $"{a} = {b}") .ToList(); if (groups.Any()) { panel.AppendLine($"> **Values**\n```cs"); panel.AppendJoin(",\n", groups); panel.AppendLine("```"); } } } break; } await Context.Channel.SendMessageAsync(panel.ToString()); }
// This is only invoked if the ID is either the Host or the Participant. public override async Task <MatchResult> InvokeAsync(SocketMessage message) { // gets the account that executed this. var account = GetAccount(message.Author.Id); // Get the input from the message string input = message.Content; // CANCEL: This cancels the current trade, regardless of who executed it. if (input == "cancel") { await SetStateAsync(TradeState.Cancel); await UpdateMessageAsync(WriteOnCancel(account)); return(MatchResult.Success); } // If the current invoker is not the current speaker, ignore their inputs if (CurrentId.HasValue) { if (CurrentId.Value != account.Id) { return(MatchResult.Continue); } } switch (State) { case TradeState.Invite: // ACCEPT if (input == "accept" && account.Id == Participant.Id) { // If the user accepted the trade invitation, go to the base trade menu. await SetStateAsync(TradeState.Menu, $"> ☑️ **{Participant.Username}** has agreed to trade."); Participant.CanTrade = false; return(MatchResult.Continue); } // DECLINE if (input == "decline" && account.Id == Participant.Id) { await SetStateAsync(TradeState.Cancel); await UpdateMessageAsync(WriteOnCancel(account)); return(MatchResult.Success); } break; case TradeState.Menu: // ACCEPT: This marks the user who executed it that they accepted their end of the trade. // If both users accept, then the trade goes through. Take all specified items from both, swap, and give both the other's items. if (input == "ready") { if (IsOfferEmpty()) { await SetStateAsync(TradeState.Menu, Format.Warning("There aren't any items specified!")); return(MatchResult.Continue); } if (CanStartTrade()) { Trade(); await SetStateAsync(TradeState.Success); return(MatchResult.Success); } MarkAsReady(account.Id); await SetStateAsync(TradeState.Menu); return(MatchResult.Continue); } if (input == "inventory") { // If someone is already inspecting their backpack, ignore input. if (CurrentId.HasValue) { return(MatchResult.Continue); } CurrentId = account.Id; await SetStateAsync(TradeState.Inventory); return(MatchResult.Continue); } break; case TradeState.Inventory: // BACK: Used by the current invoker to return to the menu. if (input == "back") { CurrentId = null; await SetStateAsync(TradeState.Menu); return(MatchResult.Continue); } // TODO: Handle unique item ID when trading. // Check if the specified item exists in the invoker inventory if (!ItemHelper.HasItem(account, input)) { await SetStateAsync(TradeState.Inventory, Format.Warning("An invalid item ID was specified.")); return(MatchResult.Continue); } // If the specified item was already selected, remove it from their trade. if (GetCurrentItems().ContainsKey(input)) { RemoveItemFromCurrent(input); await SetStateAsync(TradeState.Inventory, "> 📤 Removed the specified item from your offer."); HostReady = false; ParticipantReady = false; return(MatchResult.Continue); } ItemData selectedItem = ItemHelper.DataOf(account, input); if (!ItemHelper.CanTrade(input, selectedItem)) { await SetStateAsync(TradeState.Inventory, Format.Warning("This item is unavailable for trading.")); return(MatchResult.Continue); } AddItemToCurrent(input); await SetStateAsync(TradeState.Inventory, "> 📥 Added the specified item to your offer."); HostReady = false; ParticipantReady = false; return(MatchResult.Continue); } return(MatchResult.Continue); }