public static void TrackTrades(User user, string userOrItemName)
        {
            LinkedUser linkedUser = LinkedUserManager.LinkedUserByEcoUser(user);

            if (linkedUser == null)
            {
                ChatManager.ServerMessageToPlayer(new LocString($"You have not linked your Discord Account to DiscordLink on this Eco Server.\nLog into the game and use the `\\dl-link` command to initialize account linking."), user);
                return;
            }

            int trackedTradesCount = DLStorage.WorldData.GetTrackedTradesCountForUser(ulong.Parse(linkedUser.DiscordId));

            if (trackedTradesCount >= DLConfig.Data.MaxTrackedTradesPerUser)
            {
                ChatManager.ServerMessageToPlayer(new LocString($"You are already tracking {trackedTradesCount} trades and the limit is {DLConfig.Data.MaxTrackedTradesPerUser} tracked trades per user.\nUse the `\\dl-StopTrackTrades` command to remove a tracked trade to make space if you wish to add a new one."), user);
                return;
            }

            // Fetch trade data using the trades command once to see that the command parameters are valid
            string result = SharedCommands.Trades(userOrItemName, out string matchedName, out bool isItem, out StoreOfferList groupedBuyOffers, out StoreOfferList groupedSellOffers);

            if (!string.IsNullOrEmpty(result))
            {
                ChatManager.ServerMessageToPlayer(new LocString(result), user);
                return;
            }

            bool added = DLStorage.WorldData.AddTrackedTradeItem(ulong.Parse(linkedUser.DiscordId), matchedName).Result;

            result = added ? $"Tracking all trades for {matchedName}." : $"Failed to start tracking trades for {matchedName}";

            ChatManager.ServerMessageToPlayer(new LocString(result), user);
        }
        public static void ListTrackedTrades(User user)
        {
            LinkedUser linkedUser = LinkedUserManager.LinkedUserByEcoUser(user);

            if (linkedUser == null)
            {
                ChatManager.ServerMessageToPlayer(new LocString($"You have not linked your Discord Account to DiscordLink on this Eco Server.\nLog into the game and use the `\\dl-link` command to initialize account linking."), user);
                return;
            }

            EcoUtil.SendAnnouncementMessage("Tracked Trades", DLStorage.WorldData.ListTrackedTrades(ulong.Parse(linkedUser.DiscordId)), user);
        }
        public static void StopTrackTrades(User user, string userOrItemName)
        {
            LinkedUser linkedUser = LinkedUserManager.LinkedUserByEcoUser(user);

            if (linkedUser == null)
            {
                ChatManager.ServerMessageToPlayer(new LocString($"You have not linked your Discord Account to DiscordLink on this Eco Server.\nLog into the game and use the `\\dl-link` command to initialize account linking."), user);
                return;
            }

            bool   removed = DLStorage.WorldData.RemoveTrackedTradeItem(ulong.Parse(linkedUser.DiscordId), userOrItemName).Result;
            string result  = removed ? $"Stopped tracking trades for {userOrItemName}." : $"Failed to stop tracking trades for {userOrItemName}.\nUse `\\dl-ListTrackedStores` to see what is currently being tracked.";

            ChatManager.ServerMessageToPlayer(new LocString(result), user);
        }
 public static void UnlinkDiscordAccount(User user)
 {
     CallWithErrorHandling <object>((lUser, args) =>
     {
         bool result = LinkedUserManager.RemoveLinkedUser(user);
         if (result)
         {
             ChatManager.ServerMessageToPlayer(new LocString($"Discord account unlinked."), user);
         }
         else
         {
             ChatManager.ServerMessageToPlayer(new LocString($"No linked Discord account could be found."), user);
         }
     }, user);
 }
        public static void LinkDiscordAccount(User user, string discordName)
        {
            CallWithErrorHandling <object>((lUser, args) =>
            {
                var plugin = Plugins.DiscordLink.DiscordLink.Obj;
                if (plugin == null)
                {
                    return;
                }

                if (!DiscordUtil.BotHasIntent(DiscordIntents.GuildMembers))
                {
                    ChatManager.ServerMessageToPlayer(new LocString($"This server is not configured to use account linking as the bot lacks the elevated Guild Members Intent."), user);
                    return;
                }

                // Find the Discord user
                DiscordMember matchingMember = null;
                foreach (DiscordGuild guild in plugin.DiscordClient.Guilds.Values)
                {
                    IReadOnlyCollection <DiscordMember> guildMembers = DiscordUtil.GetGuildMembersAsync(guild).Result;
                    if (guildMembers == null)
                    {
                        continue;
                    }

                    foreach (DiscordMember member in guildMembers)
                    {
                        if (member.Id.ToString() == discordName || member.Username.ToLower() == discordName.ToLower())
                        {
                            matchingMember = member;
                            break;
                        }
                    }
                }

                if (matchingMember == null)
                {
                    ChatManager.ServerMessageToPlayer(new LocString($"No Discord account with the ID or name \"{discordName}\" could be found."), user);
                    return;
                }

                // Make sure that the accounts aren't already linked to any account
                foreach (LinkedUser linkedUser in DLStorage.PersistentData.LinkedUsers)
                {
                    if (user.SlgId == linkedUser.SlgId || user.SteamId == linkedUser.SteamId)
                    {
                        if (linkedUser.DiscordId == matchingMember.Id.ToString())
                        {
                            ChatManager.ServerMessageToPlayer(new LocString("Eco account is already linked to this Discord account.\nUse /dl-unlink to remove the existing link."), user);
                        }
                        else
                        {
                            ChatManager.ServerMessageToPlayer(new LocString("Eco account is already linked to a different Discord account.\nUse /dl-unlink to remove the existing link."), user);
                        }
                        return;
                    }
                    else if (linkedUser.DiscordId == matchingMember.Id.ToString())
                    {
                        ChatManager.ServerMessageToPlayer(new LocString("Discord account is already linked to a different Eco account."), user);
                        return;
                    }
                }

                // Create a linked user from the combined Eco and Discord info
                LinkedUserManager.AddLinkedUser(user, matchingMember.Id.ToString(), matchingMember.Guild.Id.ToString());

                // Notify the Discord account that a link has been made and ask for verification
                _ = DiscordUtil.SendDMAsync(matchingMember, null, MessageBuilder.Discord.GetVerificationDM(user));

                // Notify the Eco user that the link has been created and that verification is required
                ChatManager.ServerMessageToPlayer(new LocString($"Your account has been linked.\nThe link requires verification before becoming active.\nInstructions have been sent to the linked Discord account."), user);
            },
                                           user);
        }