From 5f7c00693000fc39639c00abde0151c65e804c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=85=B0=EF=B8=8F=F0=9F=85=B0=EF=B8=8F=F0=9F=85=B0?= =?UTF-8?q?=EF=B8=8F1=EF=B8=8F=E2=83=A36=EF=B8=8F=E2=83=A32=EF=B8=8F?= =?UTF-8?q?=E2=83=A3=20=E2=9C=94=EF=B8=8F?= Date: Mon, 5 Jan 2026 22:35:23 -0600 Subject: [PATCH] Add inventory top leaderboard special identifiers $top#____ = Top # users by specific item amount. For example, if my inventory is called "Items" and the item I want to check is called "Potion", I would use "$top5itemspotion". (EX: #1) User1 - 10, #2) User2 - 8, #3) User3 - 5) $top#____total = Top # users by total items in inventory. (EX: $top5itemstotal -> #1) User1 - 45, #2) User2 - 32, #3) User3 - 28) $top#____unique = Top # users by unique item types owned. (EX: $top5itemsunique -> #1) User1 - 12, #2) User2 - 10, #3) User3 - 8) $top____user = Get user data of #1 user for specific item. Can be combined with user special identifiers. (EX: $topitemspotionusername -> "User1") $top____totaluser = Get user data of #1 user by total items. Can be combined with user special identifiers. (EX: $topitemstotalusername -> "User1") $top____uniqueuser = Get user data of #1 user by unique items. Can be combined with user special identifiers. (EX: $topitemsuniqueusername -> "User1") --- MixItUp.Base/Model/Currency/InventoryModel.cs | 47 +++++++ .../Util/SpecialIdentifierStringBuilder.cs | 123 ++++++++++++++++++ 2 files changed, 170 insertions(+) diff --git a/MixItUp.Base/Model/Currency/InventoryModel.cs b/MixItUp.Base/Model/Currency/InventoryModel.cs index 73a44a39a..0a133e637 100644 --- a/MixItUp.Base/Model/Currency/InventoryModel.cs +++ b/MixItUp.Base/Model/Currency/InventoryModel.cs @@ -207,6 +207,30 @@ public InventoryModel() [JsonIgnore] public string UserUniqueItemsTotalSpecialIdentifier { get { return string.Format("{0}uniqueitemstotal", this.UserAmountSpecialIdentifierHeader); } } + [JsonIgnore] + public string TopItemRegexSpecialIdentifierHeader { get { return string.Format("{0}\\d+{1}", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, this.SpecialIdentifier); } } + + [JsonIgnore] + public string TopItemSpecialIdentifierHeader { get { return string.Format("{0}{1}", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, this.SpecialIdentifier); } } + + [JsonIgnore] + public string TopTotalRegexSpecialIdentifier { get { return string.Format("{0}\\d+{1}total", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, this.SpecialIdentifier); } } + + [JsonIgnore] + public string TopTotalSpecialIdentifier { get { return string.Format("{0}{1}total", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, this.SpecialIdentifier); } } + + [JsonIgnore] + public string TopTotalUserSpecialIdentifier { get { return string.Format("{0}{1}", this.TopTotalSpecialIdentifier, SpecialIdentifierStringBuilder.UserSpecialIdentifierHeader); } } + + [JsonIgnore] + public string TopUniqueRegexSpecialIdentifier { get { return string.Format("{0}\\d+{1}unique", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, this.SpecialIdentifier); } } + + [JsonIgnore] + public string TopUniqueSpecialIdentifier { get { return string.Format("{0}{1}unique", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, this.SpecialIdentifier); } } + + [JsonIgnore] + public string TopUniqueUserSpecialIdentifier { get { return string.Format("{0}{1}", this.TopUniqueSpecialIdentifier, SpecialIdentifierStringBuilder.UserSpecialIdentifierHeader); } } + [JsonIgnore] public CommandModelBase ItemsBoughtCommand { @@ -335,6 +359,29 @@ public Dictionary GetAmounts(UserV2ViewModel user) return amounts; } + public int GetTotalAmount(UserV2Model user) + { + int total = 0; + foreach (InventoryItemModel item in this.Items.Values) + { + total += this.GetAmount(user, item); + } + return total; + } + + public int GetUniqueItemCount(UserV2Model user) + { + int count = 0; + foreach (InventoryItemModel item in this.Items.Values) + { + if (this.GetAmount(user, item) > 0) + { + count++; + } + } + return count; + } + public bool HasAmount(UserV2ViewModel user, Guid itemID, int amount) { if (this.ItemExists(itemID)) diff --git a/MixItUp.Base/Util/SpecialIdentifierStringBuilder.cs b/MixItUp.Base/Util/SpecialIdentifierStringBuilder.cs index 1f1c29027..4a81bf302 100644 --- a/MixItUp.Base/Util/SpecialIdentifierStringBuilder.cs +++ b/MixItUp.Base/Util/SpecialIdentifierStringBuilder.cs @@ -389,6 +389,129 @@ await this.ReplaceNumberBasedRegexSpecialIdentifier(currency.TopRegexSpecialIden await this.HandleUserSpecialIdentifiers(topUser, currency.TopSpecialIdentifier); } } + + foreach (InventoryModel inventory in ChannelSession.Settings.Inventory.Values) + { + if (this.ContainsRegexSpecialIdentifier(inventory.TopTotalRegexSpecialIdentifier)) + { + await this.ReplaceNumberBasedRegexSpecialIdentifier(inventory.TopTotalRegexSpecialIdentifier, async (total) => + { + IEnumerable applicableUsers = await SpecialIdentifierStringBuilder.GetAllNonExemptUsers(); + List inventoryUserList = new List(); + int userPosition = 1; + foreach (UserV2Model userData in applicableUsers.OrderByDescending(u => inventory.GetTotalAmount(u)).Take(total)) + { + UserV2ViewModel userViewModel = new UserV2ViewModel(userData); + inventoryUserList.Add($"#{userPosition}) {userViewModel.Username} - {inventory.GetTotalAmount(userData).ToNumberDisplayString()}"); + userPosition++; + } + + string result = MixItUp.Base.Resources.NoUsersFound; + if (inventoryUserList.Count > 0) + { + result = string.Join(", ", inventoryUserList); + } + return result; + }); + } + + if (this.ContainsSpecialIdentifier(inventory.TopTotalUserSpecialIdentifier)) + { + IEnumerable applicableUsers = await SpecialIdentifierStringBuilder.GetAllNonExemptUsers(); + UserV2Model topUserData = applicableUsers.Top(u => inventory.GetTotalAmount(u)); + if (topUserData != null) + { + UserV2ViewModel topUser = ServiceManager.Get().GetActiveUserByID(parameters.Platform, topUserData.ID); + if (topUser == null) + { + topUser = new UserV2ViewModel(topUserData); + } + await this.HandleUserSpecialIdentifiers(topUser, inventory.TopTotalSpecialIdentifier); + } + } + + if (this.ContainsRegexSpecialIdentifier(inventory.TopUniqueRegexSpecialIdentifier)) + { + await this.ReplaceNumberBasedRegexSpecialIdentifier(inventory.TopUniqueRegexSpecialIdentifier, async (total) => + { + IEnumerable applicableUsers = await SpecialIdentifierStringBuilder.GetAllNonExemptUsers(); + List inventoryUserList = new List(); + int userPosition = 1; + foreach (UserV2Model userData in applicableUsers.OrderByDescending(u => inventory.GetUniqueItemCount(u)).Take(total)) + { + UserV2ViewModel userViewModel = new UserV2ViewModel(userData); + inventoryUserList.Add($"#{userPosition}) {userViewModel.Username} - {inventory.GetUniqueItemCount(userData).ToNumberDisplayString()}"); + userPosition++; + } + + string result = MixItUp.Base.Resources.NoUsersFound; + if (inventoryUserList.Count > 0) + { + result = string.Join(", ", inventoryUserList); + } + return result; + }); + } + + if (this.ContainsSpecialIdentifier(inventory.TopUniqueUserSpecialIdentifier)) + { + IEnumerable applicableUsers = await SpecialIdentifierStringBuilder.GetAllNonExemptUsers(); + UserV2Model topUserData = applicableUsers.Top(u => inventory.GetUniqueItemCount(u)); + if (topUserData != null) + { + UserV2ViewModel topUser = ServiceManager.Get().GetActiveUserByID(parameters.Platform, topUserData.ID); + if (topUser == null) + { + topUser = new UserV2ViewModel(topUserData); + } + await this.HandleUserSpecialIdentifiers(topUser, inventory.TopUniqueSpecialIdentifier); + } + } + + foreach (InventoryItemModel item in inventory.Items.Values) + { + string itemTopRegex = string.Format("{0}\\d+{1}{2}", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, inventory.SpecialIdentifier, item.SpecialIdentifier); + if (this.ContainsRegexSpecialIdentifier(itemTopRegex)) + { + await this.ReplaceNumberBasedRegexSpecialIdentifier(itemTopRegex, async (total) => + { + IEnumerable applicableUsers = await SpecialIdentifierStringBuilder.GetAllNonExemptUsers(); + List itemUserList = new List(); + int userPosition = 1; + foreach (UserV2Model userData in applicableUsers.OrderByDescending(u => inventory.GetAmount(u, item)).Take(total)) + { + UserV2ViewModel userViewModel = new UserV2ViewModel(userData); + itemUserList.Add($"#{userPosition}) {userViewModel.Username} - {inventory.GetAmount(userData, item).ToNumberDisplayString()}"); + userPosition++; + } + + string result = MixItUp.Base.Resources.NoUsersFound; + if (itemUserList.Count > 0) + { + result = string.Join(", ", itemUserList); + } + return result; + }); + } + + string itemTopUser = string.Format("{0}{1}{2}{3}", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, inventory.SpecialIdentifier, item.SpecialIdentifier, SpecialIdentifierStringBuilder.UserSpecialIdentifierHeader); + if (this.ContainsSpecialIdentifier(itemTopUser)) + { + IEnumerable applicableUsers = await SpecialIdentifierStringBuilder.GetAllNonExemptUsers(); + UserV2Model topUserData = applicableUsers.Top(u => inventory.GetAmount(u, item)); + if (topUserData != null) + { + UserV2ViewModel topUser = ServiceManager.Get().GetActiveUserByID(parameters.Platform, topUserData.ID); + if (topUser == null) + { + topUser = new UserV2ViewModel(topUserData); + } + string itemTopPrefix = string.Format("{0}{1}{2}", SpecialIdentifierStringBuilder.TopSpecialIdentifierHeader, inventory.SpecialIdentifier, item.SpecialIdentifier); + await this.HandleUserSpecialIdentifiers(topUser, itemTopPrefix); + } + } + } + } } foreach (CurrencyModel currency in ChannelSession.Settings.Currency.Values)