public static void FormatTrades(string matchedName, bool isItem, StoreOfferList groupedBuyOffers, StoreOfferList groupedSellOffers, out DiscordLinkEmbed embedContent) { Func <Tuple <StoreComponent, TradeOffer>, string> getLabel; if (isItem) { getLabel = t => t.Item1.Parent.Owners.Name; } else { getLabel = t => t.Item2.Stack.Item.DisplayName; } var fieldEnumerator = TradeOffersToFields(groupedBuyOffers, groupedSellOffers, getLabel); // Format message DiscordLinkEmbed embed = new DiscordLinkEmbed() .WithTitle($"Trades for {matchedName}"); if (groupedSellOffers.Count() > 0 || groupedBuyOffers.Count() > 0) { foreach (var stringTuple in fieldEnumerator) { embed.AddField(stringTuple.Item1, stringTuple.Item2); } embed.WithFooter(GetStandardEmbedFooter()); } else { embed.WithTitle($"No trade offers found for {matchedName}"); } embedContent = embed; }
public static DiscordLinkEmbed GetVerificationDM(User ecoUser) { DLConfigData config = DLConfig.Data; ServerInfo serverInfo = NetworkManager.GetServerInfo(); string serverName = MessageUtil.StripTags(!string.IsNullOrWhiteSpace(config.ServerName) ? DLConfig.Data.ServerName : MessageUtil.StripTags(serverInfo.Description)); DiscordLinkEmbed embed = new DiscordLinkEmbed(); embed.WithTitle("Account Linking Verification"); embed.AddField("Initiator", MessageUtil.StripTags(ecoUser.Name)); embed.AddField("Description", $"Your Eco account has been linked to your Discord account on the server \"{serverName}\"."); embed.AddField("Action Required", $"If you initiated this action, use the command `{config.DiscordCommandPrefix}verifylink` to verify that these accounts should be linked."); embed.WithFooter("If you did not initiate this action, notify a server admin.\nThe account link cannot be used until verified."); return(embed); }
public static DiscordLinkEmbed GetServerInfo(ServerInfoComponentFlag flag) { var plugin = DiscordLink.Obj; if (plugin == null) { return(null); } DLConfigData config = DLConfig.Data; ServerInfo serverInfo = NetworkManager.GetServerInfo(); DiscordLinkEmbed embed = new DiscordLinkEmbed(); embed.WithFooter(GetStandardEmbedFooter()); if (flag.HasFlag(ServerInfoComponentFlag.Name)) { embed.WithTitle($"**{MessageUtil.FirstNonEmptyString(config.ServerName, MessageUtil.StripTags(serverInfo.Description), "[Server Title Missing]")} " + "Server Status" + "**\n" + DateTime.Now.ToShortDateString() + " : " + DateTime.Now.ToShortTimeString()); } else { DateTime time = DateTime.Now; int utcOffset = TimeZoneInfo.Local.GetUtcOffset(time).Hours; embed.WithTitle("**" + "Server Status" + "**\n" + "[" + DateTime.Now.ToString("yyyy-MM-dd : HH:mm", CultureInfo.InvariantCulture) + " UTC " + (utcOffset != 0 ? (utcOffset >= 0 ? "+" : "-") + utcOffset : "") + "]"); } if (flag.HasFlag(ServerInfoComponentFlag.Description)) { embed.WithDescription(MessageUtil.FirstNonEmptyString(config.ServerDescription, MessageUtil.StripTags(serverInfo.Description), "No server description is available.")); } if (flag.HasFlag(ServerInfoComponentFlag.Logo) && !string.IsNullOrWhiteSpace(config.ServerLogo)) { embed.WithThumbnail(config.ServerLogo); } if (flag.HasFlag(ServerInfoComponentFlag.ConnectionInfo)) { string fieldText = "-- Connection info not configured --"; string address = string.Empty; string port = string.Empty; if (!string.IsNullOrEmpty(config.ServerAddress)) { address = config.ServerAddress; } else if (!string.IsNullOrEmpty(serverInfo.Address)) { address = serverInfo.Address; } if (!string.IsNullOrEmpty(address)) { port = serverInfo.GamePort.ToString(); fieldText = $"{address}:{port}"; } embed.AddField("Connection Info", fieldText); } if (flag.HasFlag(ServerInfoComponentFlag.PlayerCount)) { embed.AddField("Online Players Count", $"{UserManager.OnlineUsers.Where(user => user.Client.Connected).Count()}/{serverInfo.TotalPlayers}"); } if (flag.HasFlag(ServerInfoComponentFlag.PlayerList)) { IEnumerable <string> onlineUsers = UserManager.OnlineUsers.Where(user => user.Client.Connected).Select(user => user.Name); string playerList = onlineUsers.Count() > 0 ? string.Join("\n", onlineUsers) : "-- No players online --"; bool useOnlineTime = flag.HasFlag(ServerInfoComponentFlag.PlayerListLoginTime); embed.AddField("Online Players", Shared.GetPlayerList(useOnlineTime)); } if (flag.HasFlag(ServerInfoComponentFlag.CurrentTime)) { TimeSpan timeSinceStartSpan = new TimeSpan(0, 0, (int)serverInfo.TimeSinceStart); embed.AddField("Current Time", $"Day {timeSinceStartSpan.Days + 1} {timeSinceStartSpan.Hours.ToString("00")}:{timeSinceStartSpan.Minutes.ToString("00")}"); // +1 days to get start at day 1 just like ingame } if (flag.HasFlag(ServerInfoComponentFlag.TimeRemaining)) { TimeSpan timeRemainingSpan = new TimeSpan(0, 0, (int)serverInfo.TimeLeft); bool meteorHasHit = timeRemainingSpan.Seconds < 0; timeRemainingSpan = meteorHasHit ? new TimeSpan(0, 0, 0) : timeRemainingSpan; embed.AddField("Time Left Until Meteor", $"{timeRemainingSpan.Days} Days, {timeRemainingSpan.Hours} hours, {timeRemainingSpan.Minutes} minutes"); } if (flag.HasFlag(ServerInfoComponentFlag.MeteorHasHit)) { TimeSpan timeRemainingSpan = new TimeSpan(0, 0, (int)serverInfo.TimeLeft); embed.AddField("Meteor Has Hit", timeRemainingSpan.Seconds < 0 ? "Yes" : "No"); } if (flag.HasFlag(ServerInfoComponentFlag.ActiveElectionCount)) { embed.AddField("Active Elections Count", $"{EcoUtil.ActiveElections.Count()}"); } if (flag.HasFlag(ServerInfoComponentFlag.ActiveElectionList)) { string electionList = string.Empty; foreach (Election election in EcoUtil.ActiveElections) { electionList += $"{MessageUtil.StripTags(election.Name)} **[{election.TotalVotes} Votes]**\n"; } if (string.IsNullOrEmpty(electionList)) { electionList = "-- No active elections --"; } embed.AddField("Active Elections", electionList); } if (flag.HasFlag(ServerInfoComponentFlag.LawCount)) { embed.AddField("Law Count", $"{EcoUtil.ActiveLaws.Count()}"); } if (flag.HasFlag(ServerInfoComponentFlag.LawList)) { string lawList = string.Empty; foreach (Law law in EcoUtil.ActiveLaws) { lawList += $"{MessageUtil.StripTags(law.Name)}\n"; } if (string.IsNullOrEmpty(lawList)) { lawList = "-- No active laws --"; } embed.AddField("Laws", lawList); } return(embed); }
protected override void GetDisplayContent(DiscordTarget target, out List <Tuple <string, DiscordLinkEmbed> > tagAndContent) { tagAndContent = new List <Tuple <string, DiscordLinkEmbed> >(); DiscordLinkEmbed embed = new DiscordLinkEmbed(); List <WorkParty> workParties = Registrars.Get <WorkParty>().All <WorkParty>().NonNull().Where(x => x.State == ProposableState.Active).ToList(); foreach (WorkParty workParty in workParties) { string tag = $"{BaseTag} [{workParty.Id}]"; embed.WithTitle(MessageUtil.StripTags(workParty.Name)); embed.WithFooter(MessageBuilder.Discord.GetStandardEmbedFooter()); // Workers string workersDesc = string.Empty; foreach (Laborer laborer in workParty.Laborers) { if (laborer.Citizen == null) { continue; } string creator = (laborer.Citizen == workParty.Creator) ? "Creator" : string.Empty; workersDesc += $"{laborer.Citizen.Name} ({creator})\n"; } if (string.IsNullOrWhiteSpace(workersDesc)) { workersDesc += "--- No Workers Registered ---"; } embed.AddField("Workers", workersDesc); // Work foreach (Work work in workParty.Work) { string workDesc = string.Empty; string workType = string.Empty; List <string> workEntries = new List <string>(); switch (work) { case LaborWork laborWork: { if (!string.IsNullOrEmpty(laborWork.ShortDescriptionRemainingWork)) { workType = $"Labor for {laborWork.Order.Recipe.RecipeName}"; workEntries.Add(MessageUtil.StripTags(laborWork.ShortDescriptionRemainingWork)); } break; } case WorkOrderWork orderWork: { workType = $"Materials for {orderWork.Order.Recipe.RecipeName}"; foreach (TagStack stack in orderWork.Order.MissingIngredients) { string itemName = string.Empty; if (stack.Item != null) { itemName = stack.Item.DisplayName; } else if (stack.StackObject != null) { itemName = stack.StackObject.DisplayName; } workEntries.Add($"{itemName} ({stack.Quantity})"); } break; } default: break; } if (workEntries.Count > 0) { foreach (string material in workEntries) { workDesc += $"- {material}\n"; } if (!string.IsNullOrWhiteSpace(workDesc)) { string percentDone = (work.PercentDone * 100.0f).ToString("N1", CultureInfo.InvariantCulture).Replace(".0", ""); embed.AddField($"\n {workType} (Weight: {work.Weight.ToString("F1")}) ({percentDone}% completed) \n", workDesc); } } } // Payment string paymentDesc = string.Empty; foreach (Payment payment in workParty.Payment) { string desc = string.Empty; switch (payment) { case CurrencyPayment currencyPayment: { float currencyAmountLeft = currencyPayment.Amount - currencyPayment.AmountPaid; if (currencyAmountLeft > 0.0f) { desc = $"Receive **{currencyAmountLeft.ToString("F1")} {currencyPayment.Currency.Name}**" + (currencyPayment.PayType == PayType.SplitByWorkPercent ? ", split based on work performed" : ", split evenly") + (currencyPayment.PayAsYouGo ? ", paid as work is performed." : ", paid when the project finishes."); } break; } case GrantTitlePayment titlePayment: { desc = $"Receive title `{MessageUtil.StripTags(titlePayment.Title.Name)}` if work contributed is at least *{titlePayment.MinContributedPercent.ToString("F1")}%*."; break; } case KnowledgeSharePayment knowledgePayment: { if (knowledgePayment.Skills.Entries.Count > 0) { desc = $"Receive knowledge of `{MessageUtil.StripTags(knowledgePayment.ShortDescription())}` if work contributed is at least *{knowledgePayment.MinContributedPercent.ToString("F1")}%*."; } break; } case ReputationPayment reputationPayment: { float reputationAmountLeft = reputationPayment.Amount - reputationPayment.AmountPaid; desc = $"Receive **{reputationAmountLeft.ToString("F1")} reputation** from *{workParty.Creator.Name}*" + (reputationPayment.PayType == PayType.SplitByWorkPercent ? ", split based on work performed" : ", split evenly") + (reputationPayment.PayAsYouGo ? ", paid as work is performed." : ", paid when the project finishes."); break; } default: break; } if (!string.IsNullOrEmpty(desc)) { paymentDesc += $"- {desc}\n"; } } if (!string.IsNullOrWhiteSpace(paymentDesc)) { embed.AddField("Payment", paymentDesc); } if (embed.Fields.Count > 0) { tagAndContent.Add(new Tuple <string, DiscordLinkEmbed>(tag, new DiscordLinkEmbed(embed))); } embed.ClearFields(); } }
protected override void GetDisplayContent(DiscordTarget target, out List <Tuple <string, DiscordLinkEmbed> > tagAndContent) { tagAndContent = new List <Tuple <string, DiscordLinkEmbed> >(); DiscordLinkEmbed embed = new DiscordLinkEmbed(); embed.WithFooter(MessageBuilder.Discord.GetStandardEmbedFooter()); foreach (Election election in EcoUtil.ActiveElections) { string tag = $"{BaseTag} [{election.Id}]"; embed.WithTitle(MessageUtil.StripTags(election.Name)); // Proposer name embed.AddField("Proposer", election.Creator.Name); // Time left embed.AddField("Time Left", TimeFormatter.FormatSpan(election.TimeLeft)); // Process embed.AddField("Process", MessageUtil.StripTags(election.Process.Name)); // Choices if (!election.BooleanElection && election.Choices.Count > 0) { string choiceDesc = string.Empty; foreach (ElectionChoice choice in election.Choices) { choiceDesc += $"{choice.Name}\n"; } embed.AddField("Choices", choiceDesc); } // Votes string voteDesc = string.Empty; if (!election.Process.AnonymousVoting) { foreach (RunoffVote vote in election.Votes) { string topChoiceName = null; int topChoiceID = vote.RankedVotes.FirstOrDefault(); foreach (ElectionChoice choice in election.Choices) { if (choice.ID == topChoiceID) { topChoiceName = choice.Name; break; } } voteDesc += $"{vote.Voter.Name} : {topChoiceName}\n"; } } else { voteDesc = "--- Anonymous Voting ---"; } if (string.IsNullOrEmpty(voteDesc)) { voteDesc = "--- No Votes Recorded ---"; } embed.AddField($"Votes ({election.TotalVotes})", voteDesc); if (embed.Fields.Count > 0) { tagAndContent.Add(new Tuple <string, DiscordLinkEmbed>(tag, new DiscordLinkEmbed(embed))); } embed.ClearFields(); } }
protected override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { if (DLConfig.Data.TradeChannels.Count <= 0) { return; } if (!(data is IEnumerable <List <CurrencyTrade> > accumulatedTrades)) { return; } // Each entry is the summarized trade events for a player and a store foreach (List <CurrencyTrade> accumulatedTradeList in accumulatedTrades) { if (accumulatedTradeList.Count <= 0) { continue; } CurrencyTrade firstTrade = accumulatedTradeList[0]; DiscordLinkEmbed embed = new DiscordLinkEmbed(); string leftName = firstTrade.Citizen.Name; string rightName = (firstTrade.WorldObject as WorldObject).Name; embed.WithTitle($"{leftName} traded at {MessageUtil.StripTags(rightName)}"); // Go through all acumulated trade events and create a summary string boughtItemsDesc = string.Empty; float boughtTotal = 0; string soldItemsDesc = string.Empty; float soldTotal = 0; foreach (CurrencyTrade trade in accumulatedTradeList) { if (trade.BoughtOrSold == Shared.Items.BoughtOrSold.Buying) { boughtItemsDesc += trade.NumberOfItems + " X " + trade.ItemUsed.DisplayName + " * " + trade.CurrencyAmount / trade.NumberOfItems + " = " + trade.CurrencyAmount + "\n"; boughtTotal += trade.CurrencyAmount; } else if (trade.BoughtOrSold == Shared.Items.BoughtOrSold.Selling) { soldItemsDesc += trade.NumberOfItems + " X " + trade.ItemUsed.DisplayName + " * " + trade.CurrencyAmount / trade.NumberOfItems + " = " + trade.CurrencyAmount + "\n"; soldTotal += trade.CurrencyAmount; } } if (!boughtItemsDesc.IsEmpty()) { boughtItemsDesc += "\nTotal = " + boughtTotal.ToString("n2"); embed.AddField("Bought", boughtItemsDesc); } if (!soldItemsDesc.IsEmpty()) { soldItemsDesc += "\nTotal = " + soldTotal.ToString("n2"); embed.AddField("Sold", soldItemsDesc); } float subTotal = soldTotal - boughtTotal; char sign = (subTotal > 0.0f ? '+' : '-'); embed.AddField("Total", sign + Math.Abs(subTotal).ToString("n2") + " " + MessageUtil.StripTags(firstTrade.Currency.Name)); // Post the trade summary in all trade channels foreach (ChannelLink tradeChannel in DLConfig.Data.TradeChannels) { if (!tradeChannel.IsValid()) { continue; } DiscordGuild discordGuild = plugin.GuildByNameOrId(tradeChannel.DiscordGuild); if (discordGuild == null) { continue; } DiscordChannel discordChannel = discordGuild.ChannelByNameOrId(tradeChannel.DiscordChannel); if (discordChannel == null) { continue; } _ = DiscordUtil.SendAsync(discordChannel, string.Empty, embed); ++_opsCount; } } }