/* * < ----- End-User License Agreement -----> * * You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of this software without the developer’s consent. * * THIS SOFTWARE IS PROVIDED BY IIIaKa AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Developer: IIIaKa * https://t.me/iiiaka * Discord: @iiiaka * https://github.com/IIIaKa * https://umod.org/user/IIIaKa * https://codefling.com/iiiaka * https://lone.design/vendor/iiiaka/ * https://www.patreon.com/iiiaka * https://boosty.to/iiiaka * Codefling plugin page: https://codefling.com/plugins/advanced-status-demo * Codefling license: https://codefling.com/plugins/advanced-status-demo?tab=downloads_field_4 * * Lone.Design plugin page: https://lone.design/product/advanced-status-demo/ * * Copyright © 2023-2024 IIIaKa */ using System; using System.Collections.Generic; using Oxide.Core; using Oxide.Core.Plugins; namespace Oxide.Plugins { [Info("Advanced Status Demo", "IIIaKa", "0.1.4")] [Description("A plugin demonstrating the usage of the AdvancedStatus plugin through the API.")] class AdvancedStatusDemo : RustPlugin { [PluginReference] private Plugin AdvancedStatus; private const string BarID = "AdvancedStatusDemo_1";//Since one plugin can have an unlimited number of bars, each should be assigned a unique ID, within your plugin. private const string Category = "Default";//Each plugin can also have its own internal plugin categories. They can be useful if you have multiple categories of bars and want to delete all bars with a specified category using the API method DeleteCategory/DeleteCategoryForAll. By default, all bars have the category "default". private const string BarImage = "AdvancedStatusDemo_Scrap";//The name of the image file(without its extension) located in *SERVER*\data\AdvancedStatus\Images private int _itemID = -932201673;//Unique identifier for the tracked item. In this example, it's a Scrap. private ItemDefinition itemDef;//ItemDefinition of the tracked item, where we obtain information about the tracked item. private Hash _lastAmount = new Hash();//Internal list of players with the amount of tracked item, allowing for comparison and avoiding bar updates when the amount remains unchanged. //The OnAdvancedStatusLoaded hook is called after the AdvancedStatus plugin is loaded and ready to use. void OnAdvancedStatusLoaded(VersionNumber version = default) { //Although the AdvancedStatus plugin loads the entire list of images from the folder *SERVER*\data\AdvancedStatus\Images //It is recommended to call LoadImage/LoadImages during the initialization of your plugin to re-check if your images are loaded properly. AdvancedStatus?.Call("LoadImage", BarImage); //Checking all active players with tracked item, then sending a bar upon plugin initialization. foreach (var player in BasePlayer.activePlayerList) { if (!player.IsNpc) { InitPlayer(player); } } //Subscribing back to all necessary hooks. Subscribe(nameof(OnPlayerConnected)); Subscribe(nameof(OnPlayerDisconnected)); Subscribe(nameof(OnPlayerLanguageChanged)); Subscribe(nameof(OnInventoryNetworkUpdate)); } void Init() { //Unsubscribing from all hooks related to the functioning of AdvancedStatus. Unsubscribe(nameof(OnPlayerConnected)); Unsubscribe(nameof(OnPlayerDisconnected)); Unsubscribe(nameof(OnPlayerLanguageChanged)); Unsubscribe(nameof(OnInventoryNetworkUpdate)); Unsubscribe(nameof(OnAdvancedStatusLoaded)); } void OnServerInitialized() { itemDef = ItemManager.FindItemDefinition(_itemID);//Getting the ItemDefinition of a tracked item based on the specified itemID. //Check if the plugin AdvancedStatus is loaded and ready using the IsReady method. If the plugin is ready, the result will be bool true (!= null). Otherwise, it will be null. if (AdvancedStatus != null && AdvancedStatus?.Call("IsReady") != null) { //If AdvancedStatus is loaded, it's necessary to check all players and subscribe back to the hooks. OnAdvancedStatusLoaded(); } Subscribe(nameof(OnAdvancedStatusLoaded));//Do not unsubscribe from this hook after OnServerInitialized if you want to work with the AdvancedStatus plugin. } void OnPluginUnloaded(Plugin plugin) { if (plugin.Name == "AdvancedStatus") { //If the AdvancedStatus plugin has been unloaded, it's advisable to unsubscribe from all hooks related to the functioning of AdvancedStatus, to avoid unnecessary overhead. Unsubscribe(nameof(OnPlayerConnected)); Unsubscribe(nameof(OnPlayerDisconnected)); Unsubscribe(nameof(OnPlayerLanguageChanged)); Unsubscribe(nameof(OnInventoryNetworkUpdate)); } } void OnPlayerConnected(BasePlayer player) { InitPlayer(player);//Checking for a player with a tracked item, then sending a bar upon the player's connection. } void OnPlayerDisconnected(BasePlayer player, string reason) { //Removing a player from the list of tracked item amount upon the player's disconnection. _lastAmount.Remove(player.userID); } void OnPlayerLanguageChanged(BasePlayer player, string key) { //If you have custom text for each language, you can send updated text when a player switches languages. //string text = lang.GetMessage("langKey", this, player.UserIDString);//Example of retrieving text by key. string text = itemDef.displayName.english;//Since there's no language file in our example, we simply use the same text. Dictionary parameters = new Dictionary { { "Id", BarID }, { "Plugin", Name }, { "Text", text } }; /*Dictionary parameters = new Dictionary { { 0, BarID }, { 1, Name }, { 15, text } };*/ AdvancedStatus?.Call("UpdateContent", player.userID.Get(), parameters); } void OnInventoryNetworkUpdate(PlayerInventory inventory, ItemContainer container, ProtoBuf.UpdateItemContainer updateItemContainer, PlayerInventory.Type type, PlayerInventory.NetworkInventoryMode mode) { if (inventory.baseEntity is BasePlayer player && _lastAmount.ContainsKey(player.userID)) { //This hook is called every time a player's inventory changes. int amount = inventory.GetAmount(_itemID);//Checking the amount of tracked item in the player's inventory. var backpack = inventory.GetAnyBackpack(); if (backpack != null) { //Counting the amount of a tracked item in the backpack, if it exists. amount += backpack.contents.GetAmount(_itemID, false); } if (amount > 0) { //The amount of the tracked item in the player's inventory has been found, and it is greater than 0. if (amount == _lastAmount[player.userID]) { //The amount of the tracked item hasn't changed, so we simply exit. return; } //Checking if the bar exists. if ((bool)(AdvancedStatus?.Call("BarExists", player.userID.Get(), BarID, Name) ?? false)) { //The bar exists, we can simply send an update of the tracked item's amount. Dictionary parameters = new Dictionary { { "Id", BarID }, //Unique identifier for the bar in your plugin. ***This is a required field. { "Plugin", Name }, //Name of your plugin. ***This is a required field. { "SubText", amount.ToString() } //The new amount of the tracked item. }; /*Dictionary parameters = new Dictionary { { 0, BarID }, { 1, Name }, { 22, amount.ToString() } };*/ AdvancedStatus?.Call("UpdateContent", player.userID.Get(), parameters);//Calling the UpdateContent method with the passing of BasePlayer/playerID and a dictionary containing the required parameters. } else { //The bar was not found, so we need to create and send a new bar. SendBar(player, amount); } _lastAmount[player.userID] = amount;//Updating the amount value of the tracked item. } else { //Removing the bar, as the tracked item was not found in the player's inventory. AdvancedStatus?.Call("DeleteBar", player.userID.Get(), BarID, Name);//Calling the DeleteBar method with the passing of BasePlayer/playerID, ID of the bar and name of your plugin. _lastAmount[player.userID] = 0;//Setting the tracked item amount value for the player to 0. } } } private void InitPlayer(BasePlayer player) { //Obtaining the amount of the tracked item in the player's inventory by itemID. int amount = player.inventory.GetAmount(_itemID); var backpack = player.inventory.GetAnyBackpack(); if (backpack != null) { //Counting the amount of a tracked item in the backpack, if it exists. amount += backpack.contents.GetAmount(_itemID, false); } if (amount > 0) { //The tracked item is found in the player's inventory and its amount is greater than 0. SendBar(player, amount);//Creating and sending a new bar. } _lastAmount[player.userID] = amount;//Updating the amount value of the tracked item. } private void SendBar(BasePlayer player, int amount) { Dictionary parameters = new Dictionary { { "Id", BarID }, //Unique identifier for the bar in your plugin. ***This is a required field. { "Plugin", Name }, //Name of your plugin. ***This is a required field. { "BarType", "Default" }, //Type of the bar. There are 5 types: Default, Timed, TimeCounter, TimeProgress and TimeProgressCounter. { "Category", "Default" }, //Internal plugin category of the bar. { "Order", 10 }, //The position of your bar relative to others. Order is determined by increasing values(ASC). { "Height", 26 }, //The height of your bar. A standard bar is 26 pixels. { "Main_Color", "#505F75" }, //HTML Hex or RGBA color of the bar background. { "Main_Transparency", 0.7f }, //Transparency of the bar background. If you pass an RGBA color directly, you can skip this parameter. The same principle applies to all other colors as well. { "Main_Material", "assets/content/ui/uibackgroundblur.mat" }, //Material of the bar background(empty to disable). { "Image", itemDef.shortname }, //Name of the image saved in the ImageLibrary or a direct link to the image if ImageLibrary is not used. { "Image_Local", BarImage }, //The name of the image file(without its extension) located in *SERVER*\data\AdvancedStatus\Images. Leave empty to use Image. { "Is_RawImage", true }, //Which type of image will be used? True - CuiRawImageComponent. False - CuiImageComponent. { "Image_Color", "#6B7E95" }, //HTML Hex or RGBA color of the bar image. { "Image_Transparency", 1.0f }, //Transparency of the image. { "Text", itemDef.displayName.english }, //Main text. { "Text_Size", 12 }, //Size of the main text. You can set any size from 1 and up, but for the standard bar height(26px), it’s recommended to keep the font size no higher than 25–30, as larger sizes simply won’t fit. { "Text_Color", "#FFFFFF" }, //HTML Hex or RGBA color of the main text. { "Text_Transparency", 1.0f }, //Transparency of the main text. { "Text_Font", "RobotoCondensed-Bold.ttf" }, //Font of the main text. You can view the list of available fonts here: https://umod.org/guides/rust/basic-concepts-of-gui#fonts { "SubText", amount.ToString() }, //Sub text. { "SubText_Size", 12 }, //Size of the sub text. { "SubText_Color", "#FFFFFF" }, //HTML Hex or RGBA color of the sub text. { "SubText_Font", "RobotoCondensed-Bold.ttf" }, //Font of the sub text. { "SubText_Outline_Color", "0.5 0.6 0.7 0.5" }, //HTML Hex or RGBA color of the outline of the sub text. { "SubText_Outline_Distance", "0.75 0.75" }, //Distance for the outline of the sub text. }; /*Dictionary parameters = new Dictionary { { 0, BarID }, { 1, Name }, { 2, "Default" }, { 3, "Default" }, { 4, 10 }, { 5, 26 }, { 6, "#505F75" }, { -6, 0.7f }, { 7, "assets/content/ui/uibackgroundblur.mat" }, { 8, itemDef.shortname }, { 9, BarImage }, { 11, true }, { 12, "#6B7E95" }, { -12, 1.0f }, { 15, itemDef.displayName.english }, { 16, 12 }, { 17, "#FFFFFF" }, { -17, 1.0f }, { 18, "RobotoCondensed-Bold.ttf" }, { 22, amount.ToString() }, { 23, 12 }, { 24, "#FFFFFF" }, { 25, "RobotoCondensed-Bold.ttf" }, { 26, "0.5 0.6 0.7 0.5" }, { 27, "0.75 0.75" } };*/ AdvancedStatus?.Call("CreateBar", player.userID.Get(), parameters); //Calling the CreateBar method with the passing of BasePlayer/playerID and a dictionary containing the required parameters. } private Dictionary _fullParameters = new Dictionary { { "Id", "AdvancedStatusDemo_1" }, //Unique identifier for the bar in your plugin. ***This is a required field. { "Plugin", "AdvancedStatusDemo" }, //Name of your plugin. ***This is a required field. { "BarType", "Default" }, //Type of the bar. There are 5 types: Default, Timed, TimeCounter, TimeProgress and TimeProgressCounter. { "Category", "Default" }, //Internal plugin category of the bar. { "Order", 10 }, //The position of your bar relative to others. Order is determined by increasing values(ASC). { "Height", 26 }, //The height of your bar. A standard bar is 26 pixels. { "Main_Color", "#505F75" }, //HTML Hex or RGBA color of the bar background. { "Main_Transparency", 0.7f }, //Transparency of the bar background. If you pass an RGBA color directly, you can skip this parameter. The same principle applies to all other colors as well. { "Main_Material", "assets/content/ui/uibackgroundblur.mat" }, //Material of the bar background(empty to disable). { "Image", "scrap" }, //Name of the image saved in the ImageLibrary or a direct link to the image if ImageLibrary is not used. { "Image_Local", "AdvancedStatusDemo_Scrap" }, //The name of the image file(without its extension) located in *SERVER*\data\AdvancedStatus\Images. Leave empty to use Image. { "Image_Sprite", "" }, //Sprite image of the bar. Leave empty to use Image_Local or Image. { "Is_RawImage", true }, //Which type of image will be used? True - CuiRawImageComponent. False - CuiImageComponent. { "Image_Color", "#6B7E95" }, //HTML Hex or RGBA color of the bar image. { "Image_Transparency", 1.0f }, //Transparency of the image. { "Image_Outline_Color", "#000000" }, //HTML Hex or RGBA color of the outline of the bar image. { "Image_Outline_Transparency", 1f }, //Transparency of the outline of the bar image. { "Image_Outline_Distance", "0.75 0.75" }, //Distance for the outline of the bar image. { "Text", "Scrap" }, //Main text. { "Text_Size", 12 }, //Size of the main text. You can set any size from 1 and up, but for the standard bar height(26px), it’s recommended to keep the font size no higher than 25–30, as larger sizes simply won’t fit. { "Text_Color", "#FFFFFF" }, //HTML Hex or RGBA color of the main text. { "Text_Transparency", 1.0f }, //Transparency of the main text. { "Text_Font", "RobotoCondensed-Bold.ttf" }, //Font of the main text. You can view the list of available fonts here: https://umod.org/guides/rust/basic-concepts-of-gui#fonts { "Text_Offset_Horizontal", 0 }, //Horizontal offset for the main text. { "Text_Outline_Color", "#000000" }, //HTML Hex or RGBA color of the outline of the main text. { "Text_Outline_Transparency", 1f }, //Transparency of the outline of the main text. { "Text_Outline_Distance", "0.75 0.75" }, //Distance for the outline of the main text. { "SubText", "35" }, //Sub text. { "SubText_Size", 12 }, //Size of the sub text. The same recommendations apply as for the main text font size. { "SubText_Color", "#FFFFFF" }, //HTML Hex or RGBA color of the sub text. { "SubText_Transparency", 1.0f }, //Transparency of thee sub text. { "SubText_Font", "RobotoCondensed-Bold.ttf" }, //Font of the sub text. { "SubText_Outline_Color", "#8099B2" }, //HTML Hex or RGBA color of the outline of the sub text. { "SubText_Outline_Transparency", 0.5f }, //Transparency of the outline of the sub text. { "SubText_Outline_Distance", "0.75 0.75" }, //Distance for the outline of the sub text. { "TimeStampStart", Network.TimeEx.currentTimestamp }, //Responsible for specifying the start point of the time reference and 0% for TimeProgress and TimeProgressCounter bars. Used if the bar type is Timed, TimeCounter, TimeProgress or TimeProgressCounter. { "TimeStamp", Network.TimeEx.currentTimestamp + 6 }, //Specifies the end time point after which the bar will be destroyed and 100% for TimeProgress and TimeProgressCounter bars. Used if the bar type is Timed, TimeCounter, TimeProgress or TimeProgressCounter. { "TimeStampDestroy", Network.TimeEx.currentTimestamp + 3 }, //If TimeStampDestroy is specified and it is less than TimeStamp, the bar will be destroyed by TimeStampDestroy. Used if the bar type is Timed, TimeCounter, TimeProgress or TimeProgressCounter. { "Progress", (float)35 / 100f }, //Progress. From 0.0 to 1.0. { "Progress_Reverse", false }, //Progress reverse. A value of false means that the progress will increase. Used if the bar type is TimeProgress or TimeProgressCounter. { "Progress_Color", "#89B840" }, //HTML Hex or RGBA color of the progress. { "Progress_Transparency", 1f }, //Transparency of the progress. { "Progress_OffsetMin", "25 2.5" }, //Progress OffsetMin: "*left* *bottom*". { "Progress_OffsetMax", "-3.5 -3.5" }, //Progress OffsetMax: "*right* *top*". { "Command", "info" }, //If the field is not empty, the bar becomes clickable, and the specified command is executed upon clicking. Note: the command must be covalence. { "PlayerCommands", new string[] { "kit" } }, //>The list type can be: List, HashSet, or string[]. A list of client commands that will be invoked when the bar is removed. Currently, there are only 2 parameters for the player whose bar is being removed: *userId* - userID and *userName* - username. { "ConsoleCommands", new List() { "o.grant user *userId* realpve.vip 3600" } }, //>A list of console(server-side) commands that will be invoked when the bar is removed. Currently, there are only 2 parameters for the player whose bar is being removed: *userId* - userID and *userName* - username. }; //NOTE: Using int as a key instead of string can improve performance but may reduce code readability. //Therefore, it's recommended to start with string keys while setting up your bars and once configuration is complete, you can switch to int for improved efficiency. private Dictionary _fullParameters2 = new Dictionary { { 0, "AdvancedStatusDemo_1" }, //"Id" - Unique identifier for the bar in your plugin. ***This is a required field. { 1, "AdvancedStatusDemo" }, //"Plugin" - Name of your plugin. ***This is a required field. { 2, "Default" }, //"BarType" - Type of the bar. There are 5 types: Default, Timed, TimeCounter, TimeProgress and TimeProgressCounter. { 3, "Default" }, //"Category" - Internal plugin category of the bar. { 4, 10 }, //"Order" - The position of your bar relative to others. Order is determined by increasing values(ASC). { 5, 26 }, //"Height" - The height of your bar. A standard bar is 26 pixels. { 6, "#505F75" }, //"Main_Color" - HTML Hex or RGBA color of the bar background. { -6, 0.7f }, //"Main_Transparency" - Transparency of the bar background. If you pass an RGBA color directly, you can skip this parameter. The same principle applies to all other colors as well. { 7, "assets/content/ui/uibackgroundblur.mat" }, //"Main_Material" - Material of the bar background(empty to disable). { 8, "scrap" }, //"Image" - Name of the image saved in the ImageLibrary or a direct link to the image if ImageLibrary is not used. { 9, "AdvancedStatusDemo_Scrap" }, //"Image_Local" - The name of the image file(without its extension) located in *SERVER*\data\AdvancedStatus\Images. Leave empty to use Image. { 10, "" }, //"Image_Sprite" - Sprite image of the bar. Leave empty to use Image_Local or Image. { 11, true }, //"Is_RawImage" - Which type of image will be used? True - CuiRawImageComponent. False - CuiImageComponent. { 12, "#6B7E95" }, //"Image_Color" - HTML Hex or RGBA color of the bar image. { -12, 1.0f }, //"Image_Transparency" - Transparency of the image. { 13, "#000000" }, //"Image_Outline_Color" - HTML Hex or RGBA color of the outline of the bar image. { -13, 1f }, //"Image_Outline_Transparency" - Transparency of the outline of the bar image. { 14, "0.75 0.75" }, //"Image_Outline_Distance" - Distance for the outline of the bar image. { 15, "Scrap" }, //"Text" - Main text. { 16, 12 }, //"Text_Size" - Size of the main text. You can set any size from 1 and up, but for the standard bar height(26px), it’s recommended to keep the font size no higher than 25–30, as larger sizes simply won’t fit. { 17, "#FFFFFF" }, //"Text_Color" - HTML Hex or RGBA color of the main text. { -17, 1.0f }, //"Text_Transparency" - Transparency of the main text. { 18, "RobotoCondensed-Bold.ttf" }, //"Text_Font" - Font of the main text. You can view the list of available fonts here: https://umod.org/guides/rust/basic-concepts-of-gui#fonts { 19, 0 }, //"Text_Offset_Horizontal" - Horizontal offset for the main text. { 20, "#000000" }, //"Text_Outline_Color" - HTML Hex or RGBA color of the outline of the main text. { -20, 1f }, //"Text_Outline_Transparency" - Transparency of the outline of the main text. { 21, "0.75 0.75" }, //"Text_Outline_Distance" - Distance for the outline of the main text. { 22, "35" }, //"SubText" - Sub text. { 23, 12 }, //"SubText_Size" - Size of the sub text. The same recommendations apply as for the main text font size. { 24, "#FFFFFF" }, //"SubText_Color" - HTML Hex or RGBA color of the sub text. { -24, 1.0f }, //"SubText_Transparency" - Transparency of thee sub text. { 25, "RobotoCondensed-Bold.ttf" }, //"SubText_Font" - Font of the sub text. { 26, "#8099B2" }, //"SubText_Outline_Color" - HTML Hex or RGBA color of the outline of the sub text. { -26, 0.5f }, //"SubText_Outline_Transparency" - Transparency of the outline of the sub text. { 27, "0.75 0.75" }, //"SubText_Outline_Distance" - Distance for the outline of the sub text. { 28, Network.TimeEx.currentTimestamp }, //"TimeStampStart" - Responsible for specifying the start point of the time reference and 0% for TimeProgress and TimeProgressCounter bars. Used if the bar type is Timed, TimeCounter, TimeProgress or TimeProgressCounter. { 29, Network.TimeEx.currentTimestamp + 6 }, //"TimeStamp" - Specifies the end time point after which the bar will be destroyed and 100% for TimeProgress and TimeProgressCounter bars. Used if the bar type is Timed, TimeCounter, TimeProgress or TimeProgressCounter. { 30, Network.TimeEx.currentTimestamp + 3 }, //"TimeStampDestroy" - If TimeStampDestroy is specified and it is less than TimeStamp, the bar will be destroyed by TimeStampDestroy. Used if the bar type is Timed, TimeCounter, TimeProgress or TimeProgressCounter. { 31, (float)35 / 100f }, //"Progress" - Progress. From 0.0 to 1.0. { 32, false }, //"Progress_Reverse" - Progress reverse. A value of false means that the progress will increase. Used if the bar type is TimeProgress or TimeProgressCounter. { 33, "#89B840" }, //"Progress_Color" - HTML Hex or RGBA color of the progress. { -33, 1f }, //"Progress_Transparency" - Transparency of the progress. { 34, "25 2.5" }, //"Progress_OffsetMin" - Progress OffsetMin: "*left* *bottom*". { 35, "-3.5 -3.5" }, //"Progress_OffsetMax" - Progress OffsetMax: "*right* *top*". { 36, "info" }, //"Command" - If the field is not empty, the bar becomes clickable, and the specified command is executed upon clicking. Note: the command must be covalence. { 37, new string[] { "kit" } }, //"PlayerCommands" - >The list type can be: List, HashSet, or string[]. A list of client commands that will be invoked when the bar is removed. Currently, there are only 2 parameters for the player whose bar is being removed: *userId* - userID and *userName* - username. { 38, new List() { "o.grant user *userId* realpve.vip 3600" } }, //"ConsoleCommands" - >A list of console(server-side) commands that will be invoked when the bar is removed. Currently, there are only 2 parameters for the player whose bar is being removed: *userId* - userID and *userName* - username. }; } }