protected override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { if (!Initialized) { return; } string username; string content; if (data is ChatSent ecoMessage) { username = ecoMessage.Citizen.Name; content = ecoMessage.Message; } else if (data is DiscordMessage discordMessage) { username = discordMessage.Author.Username; content = discordMessage.Content; } else { return; } DateTime time = DateTime.Now; int utcOffset = TimeZoneInfo.Local.GetUtcOffset(time).Hours; _writer.WriteLine("[Discord] [" + DateTime.Now.ToString("yyyy-MM-dd : HH:mm", CultureInfo.InvariantCulture) + " UTC " + (utcOffset != 0 ? (utcOffset >= 0 ? "+" : "-") + utcOffset : "") + "] " + $"{MessageUtil.StripTags(username) + ": " + MessageUtil.StripTags(content)}"); ++_opsCount; }
/// <summary> /// Called when mod is loaded /// </summary> public override void OnModLoad() { GlobalLogger = string.IsNullOrEmpty(TestVersion) ? new Logger(DiscordLogLevel.Warning) : new Logger(DiscordLogLevel.Debug); GlobalLogger.Info($"Using Discord Extension Version: {GetExtensionVersion}"); AppDomain.CurrentDomain.UnhandledException += (sender, exception) => { GlobalLogger.Exception("An exception was thrown!", exception.ExceptionObject as Exception); }; string configPath = Path.Combine(Interface.Oxide.InstanceDirectory, "discord.config.json"); if (!File.Exists(configPath)) { DiscordConfig = new DiscordConfig(configPath); DiscordConfig.Save(); } DiscordConfig = ConfigFile.Load <DiscordConfig>(configPath); DiscordConfig.Save(); DiscordLink = new DiscordLink(GlobalLogger); DiscordCommand = new DiscordCommand(DiscordConfig.Commands.CommandPrefixes); DiscordSubscriptions = new DiscordSubscriptions(GlobalLogger); Manager.RegisterLibrary(nameof(DiscordLink), DiscordLink); Manager.RegisterLibrary(nameof(DiscordCommand), DiscordCommand); Manager.RegisterLibrary(nameof(DiscordSubscriptions), DiscordSubscriptions); Interface.Oxide.RootPluginManager.OnPluginAdded += DiscordClient.OnPluginAdded; Interface.Oxide.RootPluginManager.OnPluginRemoved += DiscordClient.OnPluginRemoved; }
protected override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { if (!(data is DiscordMessage message)) { return; } if (message.IsDm()) { return; } bool isSnippetChannel = false; foreach (ChannelLink link in DLConfig.Data.SnippetChannels) { if (!link.IsValid()) { continue; } if (link.DiscordGuild.ToLower() == message.Channel.Guild.Name.ToLower() && link.DiscordChannel == message.Channel.Name) { isSnippetChannel = true; break; } } if (isSnippetChannel) { await ReloadSnippets(); } }
public async void IrcServerDisconnect(object sender, EventArgs e) { foreach (var channel in Config.DiscordServer.ChannelMapping) { await DiscordLink.SendMessage(Config.DiscordServer.GuildId, channel.Discord, $"{DiscordMessageHelper.BoldControlCode}Bridge Down:{DiscordMessageHelper.BoldControlCode} Irc Connection Severed. Attempting to reconnect..."); } }
private async Task ReloadSnippets() { DiscordLink plugin = DiscordLink.Obj; if (plugin == null) { return; } foreach (ChannelLink snippetChannel in DLConfig.Data.SnippetChannels) { // Fetch the channel and validate permissions if (!snippetChannel.IsValid()) { continue; } DiscordGuild discordGuild = plugin.GuildByNameOrId(snippetChannel.DiscordGuild); if (discordGuild == null) { continue; } DiscordChannel discordChannel = discordGuild.ChannelByNameOrId(snippetChannel.DiscordChannel); if (discordChannel == null) { continue; } if (!DiscordUtil.ChannelHasPermission(discordChannel, Permissions.ReadMessageHistory)) { continue; } IReadOnlyList <DiscordMessage> snippetChannelMessages = await DiscordUtil.GetMessagesAsync(discordChannel); if (snippetChannelMessages == null) { continue; } // Go though all the found messages and look for snippet messages matching our regex DLStorage.Instance.Snippets.Clear(); foreach (DiscordMessage channelMessage in snippetChannelMessages) { Match match = MessageUtil.SnippetRegex.Match(channelMessage.Content); if (match.Groups.Count == 3) { DLStorage.Instance.Snippets.Add(match.Groups[1].Value.ToLower(), match.Groups[2].Value); } } } }
public void IrcChannelMessage(object s, IrcMessageEventArgs e) { //_EventLog("Channel Message Received"); //_EventLog($"{e.ChannelMessage.User} {e.ChannelMessage.Channel} {e.ChannelMessage.Message}"); var link = FindIrcChannelLink(e.Message.Destination); if (null != link) { string parsedMessage = ParseIrcMessageForUsers(e.Message.Message); string message = e.Message.IsAction ? $"_*{e.Message.SourceUser} {parsedMessage} *_" : $"<{e.Message.SourceUser}> {parsedMessage}"; _ = DiscordLink.SendMessage(Config.DiscordServer.GuildId, link.Discord, message.IrcToDiscordStrikeThrough().IrcToDiscordUnderline().IrcToDiscordItalics().IrcToDiscordBold()); } }
private async Task FindMessages(DiscordLink plugin) { _channelDisplays.Clear(); foreach (ChannelLink channelLink in GetChannelLinks()) { if (!channelLink.IsValid()) { continue; } DiscordGuild discordGuild = plugin.GuildByNameOrId(channelLink.DiscordGuild); if (discordGuild == null) { continue; } DiscordChannel discordChannel = discordGuild.ChannelByNameOrId(channelLink.DiscordChannel); if (discordChannel == null) { continue; } if (!DiscordUtil.ChannelHasPermission(discordChannel, Permissions.ReadMessageHistory)) { continue; } ChannelDisplayData data = new ChannelDisplayData(channelLink); _channelDisplays.Add(data); IReadOnlyList <DiscordMessage> channelMessages = await DiscordUtil.GetMessagesAsync(discordChannel); if (channelMessages == null) { _channelDisplays.Clear(); return; } foreach (DiscordMessage message in channelMessages) { if (!message.Content.StartsWith(BaseTag)) { continue; } data.MessageIDs.Add(message.Id); } } _dirty = false; }
protected override async Task UpdateInternal(DiscordLink plugin, TriggerType trigger, object data) { if (!(data is CurrencyTrade tradeEvent)) { return; } bool citizenIsBuyer = (tradeEvent.Citizen.Id == tradeEvent.Buyer.Id); Tuple <int, int> iDTuple = new Tuple <int, int>(tradeEvent.Citizen.Id, citizenIsBuyer ? tradeEvent.Seller.Id : tradeEvent.Buyer.Id); _accumulatedTrades.TryGetValue(iDTuple, out List <CurrencyTrade> trades); if (trades == null) { trades = new List <CurrencyTrade>(); _accumulatedTrades.Add(iDTuple, trades); } trades.Add(tradeEvent); }
protected override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { if (!(data is DiscordMessage message)) { return; } ChatChannelLink channelLink = plugin.GetLinkForEcoChannel(message.Channel.Name) ?? plugin.GetLinkForEcoChannel(message.Channel.Id.ToString()); string channel = channelLink?.EcoChannel; if (string.IsNullOrWhiteSpace(channel)) { return; } if (channelLink.Direction == ChatSyncDirection.DiscordToEco || channelLink.Direction == ChatSyncDirection.Duplex) { await ForwardMessageToEcoChannel(plugin, message, channel); } }
public virtual async Task Update(DiscordLink plugin, TriggerType trigger, object data) { if (plugin == null) { return; } if ((GetTriggers() & trigger) == 0) { return; } using (await _overlapLock.LockAsync()) // Make sure that the Update function doesn't get overlapping executions { if (IsShuttingDown) { return; } await UpdateInternal(plugin, trigger, data); } }
public async Task InitializeBridge(bool initIrc = true, bool initDiscord = true) { config = ConfigHelper.LoadConfig(); if (initIrc) { IrcLink = new IrcService(Logger, config.IRCServer); } if (initDiscord) { DiscordLink = new DiscordService(Logger, config.DiscordServer); } glue = new BridgeService(IrcLink, DiscordLink, config); if (initDiscord) { DiscordLink.OnChannelMessage += glue.DiscordChannelMessage; DiscordLink.OnGuildConnected += glue.DiscordGuildConnected; DiscordLink.OnUserUpdated += glue.DiscordUserUpdated; DiscordLink.OnUserJoin += glue.DiscordUserJoined; DiscordLink.OnUserLeave += glue.DiscordUserLeave; } if (initIrc) { IrcLink.OnChannelMessage += glue.IrcChannelMessage; IrcLink.OnPrivateMessage += glue.IrcPrivateMessage; IrcLink.OnServerDisconnect += glue.IrcServerDisconnect; IrcLink.OnServerConnect += glue.IrcServerConnect; } // Start the Async Processing if (initDiscord) { DiscordLink.MainAsync().GetAwaiter(); } if (initIrc) { IrcLink.StartBridge(); // Sort of Async.. Fix this later } }
public virtual async Task Update(DiscordLink plugin, DLEventType trigger, object data) { if (plugin == null) { return; } // Check if this module should execute on the supplied trigger if ((GetTriggers() & trigger) == 0) { return; } using (await _overlapLock.LockAsync()) // Make sure that the Update function doesn't get overlapping executions { if (_isShuttingDown) { return; } await UpdateInternal(plugin, trigger, data); } }
protected override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { if (!(data is ChatSent message)) { return; } // Remove the # character from the start. var channelLink = plugin.GetLinkForDiscordChannel(message.Tag.Substring(1)); var channel = channelLink?.DiscordChannel; var guild = channelLink?.DiscordGuild; if (string.IsNullOrWhiteSpace(channel) || string.IsNullOrWhiteSpace(guild)) { return; } if (channelLink.Direction == ChatSyncDirection.EcoToDiscord || channelLink.Direction == ChatSyncDirection.Duplex) { ForwardMessageToDiscordChannel(plugin, message, channel, guild, channelLink.HereAndEveryoneMentionPermission); } }
public async Task Login() { var currentUser = Context.User; // Check to make sure the user is not already linked var alreadyLinkedUser = await database.Users .AsQueryable() .Where(x => x.DiscordId == currentUser.Id.ToString()) .FirstOrDefaultAsync(); if (alreadyLinkedUser != null) { await ReplyAsync( $@"{currentUser.Mention} your account is already linked with the email, {alreadyLinkedUser.Email}." + "If you would like to unlink you account you can use the `!unlink` command." ); return; } var linkKey = Guid.NewGuid().ToString().Replace("-", "") + Guid.NewGuid().ToString().Replace("-", ""); var discordId = currentUser.Id; var discordLink = new DiscordLink() { DiscordId = discordId.ToString(), LinkKey = linkKey }; database.Add(discordLink); await database.SaveChangesAsync(); await ReplyAsync($"{currentUser.Mention} a direct message has been sent with further instructions for setting up your account."); await currentUser.SendMessageAsync( "Please login to your NTime account using the following link to link your discord account to your NTime account " + configuration["WebsiteLink"] + "auth/login?discordLink=" + linkKey ); }
protected override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { if (!(data is WorkOrderAction craftingEvent)) { return; } if (craftingEvent.Citizen == null) { return; // Happens when a crafting table contiues crafting after finishing an item } if (craftingEvent.MarkedUpName != "Create Work Order") { return; // Happens when a player feeds materials to a blocked work order } string itemName = craftingEvent.OrderCount > 1 ? craftingEvent.CraftedItem.DisplayNamePlural : craftingEvent.CraftedItem.DisplayName; string message = $"**{craftingEvent.Citizen.Name}** started crafting {craftingEvent.OrderCount} `{itemName}` at {(craftingEvent.WorldObject as WorldObject).Name}."; foreach (ChannelLink craftingChannel in DLConfig.Data.CraftingChannels) { if (!craftingChannel.IsValid()) { continue; } DiscordGuild discordGuild = plugin.GuildByNameOrId(craftingChannel.DiscordGuild); if (discordGuild == null) { continue; } DiscordChannel discordChannel = discordGuild.ChannelByNameOrId(craftingChannel.DiscordChannel); if (discordChannel == null) { continue; } await DiscordUtil.SendAsync(discordChannel, message); ++_opsCount; } }
private void ForwardMessageToDiscordChannel(DiscordLink plugin, ChatSent chatMessage, string channelNameOrId, string guildNameOrId, GlobalMentionPermission globalMentionPermission) { Logger.DebugVerbose("Sending Eco message to Discord channel " + channelNameOrId + " in guild " + guildNameOrId); var guild = plugin.GuildByNameOrId(guildNameOrId); if (guild == null) { Logger.Error("Failed to forward Eco message from user " + MessageUtil.StripTags(chatMessage.Citizen.Name) + " as no guild with the name or ID " + guildNameOrId + " exists"); return; } var channel = guild.ChannelByNameOrId(channelNameOrId); if (channel == null) { Logger.Error("Failed to forward Eco message from user " + MessageUtil.StripTags(chatMessage.Citizen.Name) + " as no channel with the name or ID " + channelNameOrId + " exists in the guild " + guild.Name); return; } bool allowGlobalMention = (globalMentionPermission == GlobalMentionPermission.AnyUser || globalMentionPermission == GlobalMentionPermission.Admin && chatMessage.Citizen.IsAdmin); _ = DiscordUtil.SendAsync(channel, MessageUtil.FormatMessageForDiscord(chatMessage.Message, channel, chatMessage.Citizen.Name, allowGlobalMention)); }
private async Task FindMessages(DiscordLink plugin) { _targetDisplays.Clear(); foreach (DiscordTarget target in GetDiscordTargets()) { IReadOnlyList <DiscordMessage> targetMessages = null; ChannelLink channelLink = target as ChannelLink; UserLink userLink = target as UserLink; if (channelLink == null && userLink == null) { continue; } TargetDisplayData data = new TargetDisplayData(target); _targetDisplays.Add(data); if (channelLink != null) { if (!channelLink.IsValid()) { continue; } // Get the channel and verify permissions DiscordGuild discordGuild = plugin.GuildByNameOrId(channelLink.DiscordGuild); if (discordGuild == null) { continue; } DiscordChannel discordChannel = discordGuild.ChannelByNameOrId(channelLink.DiscordChannel); if (discordChannel == null) { continue; } if (!DiscordUtil.ChannelHasPermission(discordChannel, Permissions.ReadMessageHistory)) { continue; } targetMessages = await DiscordUtil.GetMessagesAsync(discordChannel); } else if (userLink != null) { DiscordDmChannel dmChannel = await userLink.Member.CreateDmChannelAsync(); targetMessages = await dmChannel.GetMessagesAsync(); } if (targetMessages == null) { // There was an error or no messages exist - Clean up and return _targetDisplays.Clear(); return; } // Go through the messages and find any our tagged messages foreach (DiscordMessage message in targetMessages) { if (!message.Content.StartsWith(BaseTag)) { continue; } data.MessageIDs.Add(message.Id); } } _dirty = false; }
public async Task Disconnect() { await IrcLink?.Disconnect(); await DiscordLink?.Disconnect(); }
protected sealed override async Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data) { // Avoid hitting the rate limitation by not allowig events that can be fired often to pass straight through. if ((trigger & HighFrequencyTriggerFlags) == trigger) { if (_HighFrequencyEventTimer == null) { _HighFrequencyEventTimer = new Timer(this.TriggerTimedUpdate, null, HighFrequencyEventDelayMS, Timeout.Infinite); } return; } if (_dirty || _targetDisplays.Count <= 0) { await FindMessages(plugin); if (_dirty || _targetDisplays.Count <= 0) { return; // If something went wrong, we should just retry later } } bool createdOrDestroyedMessage = false; List <string> matchedTags = new List <string>(); List <DiscordMessage> unmatchedMessages = new List <DiscordMessage>(); foreach (TargetDisplayData channelDisplayData in _targetDisplays) { DiscordTarget target = channelDisplayData.Target; ChannelLink channelLink = target as ChannelLink; UserLink userLink = target as UserLink; if (channelLink == null && userLink == null) { continue; } DiscordChannel targetChannel = null; if (channelLink != null) { // Get the channel and verify permissions DiscordGuild discordGuild = plugin.GuildByNameOrId(channelLink.DiscordGuild); if (discordGuild == null) { continue; } targetChannel = discordGuild.ChannelByNameOrId(channelLink.DiscordChannel); if (targetChannel == null) { continue; } if (!DiscordUtil.ChannelHasPermission(targetChannel, Permissions.ReadMessageHistory)) { continue; } } else if (userLink != null) { targetChannel = await userLink.Member.CreateDmChannelAsync(); } GetDisplayContent(target, out List <Tuple <string, DiscordLinkEmbed> > tagsAndContent); foreach (ulong messageID in channelDisplayData.MessageIDs) { DiscordMessage message = await DiscordUtil.GetMessageAsync(targetChannel, messageID); if (message == null) { _dirty = true; return; // We cannot know which messages are wrong and duplicates may be created if we continue. } if (!message.Content.StartsWith(BaseTag)) { continue; // The message belongs to a different display } bool found = false; foreach (var tagAndContent in tagsAndContent) { if (message.Content.Contains(tagAndContent.Item1)) { _ = DiscordUtil.ModifyAsync(message, tagAndContent.Item1, tagAndContent.Item2); matchedTags.Add(tagAndContent.Item1); found = true; ++_opsCount; break; } } if (!found) { unmatchedMessages.Add(message); } } // Delete the messages that are no longer relevant foreach (DiscordMessage message in unmatchedMessages) { DiscordUtil.DeleteAsync(message).Wait(); createdOrDestroyedMessage = true; ++_opsCount; } unmatchedMessages.Clear(); // Send the messages that didn't already exist foreach (var tagAndContent in tagsAndContent) { if (!matchedTags.Contains(tagAndContent.Item1)) { DiscordUtil.SendAsync(targetChannel, tagAndContent.Item1, tagAndContent.Item2).Wait(); createdOrDestroyedMessage = true; ++_opsCount; } } matchedTags.Clear(); } if (createdOrDestroyedMessage) { await FindMessages(plugin); } LastUpdateTime = DateTime.Now; }
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; } } }
public static string StoreCurrencyName(StoreComponent store) { //TODO Remove unnecessary coupling to DiscordLink return(DiscordLink.StripTags(store.Parent.GetComponent <CreditComponent>().CurrencyName)); }
protected abstract Task UpdateInternal(DiscordLink plugin, DLEventType trigger, object data);
private async Task ForwardMessageToEcoChannel(DiscordLink plugin, DiscordMessage message, string ecoChannel) { Logger.DebugVerbose("Sending Discord message to Eco channel: " + ecoChannel); ChatManager.SendChat(await MessageUtil.FormatMessageForEco(message, ecoChannel), plugin.EcoUser); ++_opsCount; }
private async Task PostAccumulatedTrades() { foreach (List <CurrencyTrade> accumulatedTrades in _accumulatedTrades.Values) { if (accumulatedTrades.Count <= 0) { continue; } CurrencyTrade firstTrade = accumulatedTrades[0]; DiscordEmbedBuilder builder = new DiscordEmbedBuilder(); string leftName = firstTrade.Citizen.Name; string rightName = firstTrade.Citizen.Id == firstTrade.Buyer.Id ? firstTrade.Seller.Name : firstTrade.Buyer.Name; builder.Title = leftName + " traded with " + rightName; string boughtItemsDesc = string.Empty; float boughtTotal = 0; string soldItemsDesc = string.Empty; float soldTotal = 0; foreach (CurrencyTrade trade in accumulatedTrades) { 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"); builder.AddField("Bought", boughtItemsDesc); } if (!soldItemsDesc.IsEmpty()) { soldItemsDesc += "\nTotal = " + soldTotal.ToString("n2"); builder.AddField("Sold", soldItemsDesc); } float subTotal = soldTotal - boughtTotal; char sign = (subTotal > 0.0f ? '+' : '-'); builder.AddField("Total", sign + Math.Abs(subTotal).ToString("n2") + " " + firstTrade.Currency.Name); DiscordLink plugin = DiscordLink.Obj; if (plugin == null) { return; } 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, "", builder.Build()); } } _accumulatedTrades.Clear(); }