/***********************************************************************************************************************/ /*** DO NOT edit this file! Edit the files under `oxide/config` and/or `oxide/lang`, created once plugin has loaded. ***/ /*** Please note, support cannot be provided if the plugin has been modified. Please use a fresh copy if modified. ***/ /***********************************************************************************************************************/ //#define DEBUG using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Oxide.Core.Libraries.Covalence; using Oxide.Core.Plugins; // TODO: Add optional arg to put items in specific slots // TODO: Add optional arg to use a custom name for items (Rust only) namespace Oxide.Plugins { #if SEVENDAYSTODIE using UnityEngine; #elif REIGNOFKINGS using CodeHatch.Engine.Networking; using CodeHatch.Inventory.Blueprints; using CodeHatch.Inventory.Blueprints.Components; using CodeHatch.ItemContainer; using UnityEngine; #endif [Info("Give", "Wulf", "3.4.1")] [Description("Allows players with permission to give items or kits")] public class Give : CovalencePlugin { #region Configuration private Configuration _config; public class Configuration { // TODO: Add optional cooldown for commands [JsonProperty("Item blacklist (name or item ID)", ObjectCreationHandling = ObjectCreationHandling.Replace)] public List ItemBlacklist = new List(); [JsonProperty("Log usage to console")] public bool LogToConsole = false; //[JsonProperty("Log usage to file")] // TODO: Implement logging options //public bool LogToFile = false; //[JsonProperty("Rotate logs daily")] // TODO: Implement logging options //public bool RotateLogs = true; [JsonProperty("Show chat notices")] public bool ShowChatNotices = false; #if RUST [JsonProperty("Show popup notices")] public bool ShowPopupNotices = false; #endif public string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } protected override void LoadDefaultConfig() => _config = new Configuration(); protected override void LoadConfig() { base.LoadConfig(); try { _config = Config.ReadObject(); if (_config == null) { throw new JsonException(); } if (!_config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) { LogWarning("Configuration appears to be outdated; updating and saving"); SaveConfig(); } } catch { LogWarning($"Configuration file {Name}.json is invalid; using defaults"); LoadDefaultConfig(); } } protected override void SaveConfig() { LogWarning($"Configuration changes saved to {Name}.json"); Config.WriteObject(_config, true); } #endregion Configuration #region Localization protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["CommandGive"] = "give", ["CommandGiveAll"] = "giveall", ["CommandGiveArm"] = "givearm", ["CommandGiveTo"] = "giveto", ["CommandGiveKit"] = "givekit", ["CommandGiveKitTo"] = "givekitto", ["CommandGiveKitAll"] = "givekitall", ["GiveKitAllFail"] = "Could not give kit '{0}' to {1} player(s)", ["GiveKitAllSuccess"] = "Gave kit '{0}' to {1} player(s)", ["GiveKitFail"] = "Could not give kit '{0}' to yourself", ["GiveKitSuccess"] = "Gave kit '{0}' to yourself", ["GiveKitToFail"] = "Could not give kit '{0}' to '{1}'", ["GiveKitToSuccess"] = "Gave kit '{0}' to '{1}'", ["GiveAllFail"] = "Could not give item {0} x {1} to {2} player(s)", ["GiveAllSuccess"] = "Gave item {0} x {1} to {2} player(s)", ["GiveFail"] = "Could not give item {0} x {1} to yourself", ["GiveSuccess"] = "Gave item {0} x {1} to yourself", ["GiveToFail"] = "Could not give item {0} x {1} to '{2}'", ["GiveToSuccess"] = "Gave item {0} x {1} to '{2}'", ["InvalidItem"] = "{0} is not a valid item or is blacklisted", ["InvalidKit"] = "{0} is not a valid kit", ["ItemNotFound"] = "Could not find any item by name or ID '{0}' to give", ["ItemReceived"] = "You've received {0} x {1}", ["KitsUnavailable"] = "Kits plugin is not installed or is not loaded", ["NotAllowed"] = "You are not allowed to use the '{0}' command", ["NoPlayersConnected"] = "There are no players connected to give items to", ["NoPlayersFound"] = "No players found with name or ID '{0}'", ["PlayersFound"] = "Multiple players were found, please specify: {0}", ["PlayersOnly"] = "Command '{0}' can only be used by a player", ["PlayerNotConnected"] = "Unable to give to player '{0} ({1})', not connected", #if RUST ["UsageGive"] = "Usage: {0} [amount] [condition fraction] [skin id]", ["UsageGiveAll"] = "Usage: {0} [amount] [skin id]", ["UsageGiveTo"] = "Usage: {0} [amount] [skin id]", ["UsageGiveArm"] = "Usage: {0} [amount] [skin id]", #else ["UsageGive"] = "Usage: {0} [amount]", ["UsageGiveAll"] = "Usage: {0} [amount]", ["UsageGiveTo"] = "Usage: {0} [amount]", ["UsageGiveArm"] = "Usage: {0} [amount]", #endif ["UsageGiveKit"] = "Usage: {0} ", ["UsageGiveKitTo"] = "Usage: {0} ", ["UsageGiveKitAll"] = "Usage: {0} " }, this); } #endregion Localization #region Initialization #if HURTWORLD [PluginReference("HWKits")] private Plugin Kits; #else [PluginReference] private Plugin Kits; #endif private const string PermissionGive = "give.self"; private const string PermissionGiveAll = "give.all"; #if REIGNOFKINGS || RUST private const string PermissionGiveArm = "give.arm"; #endif private const string PermissionGiveTo = "give.to"; private const string PermissionGiveKit = "give.kit"; private const string PermissionGiveKitAll = "give.kitall"; private const string PermissionGiveKitTo = "give.kitto"; private const string PermissionBypassBlacklist = "give.bypassblacklist"; private void Init() { permission.RegisterPermission(PermissionGive, this); permission.RegisterPermission(PermissionGiveAll, this); #if REIGNOFKINGS || RUST permission.RegisterPermission(PermissionGiveArm, this); #endif permission.RegisterPermission(PermissionGiveTo, this); permission.RegisterPermission(PermissionGiveKit, this); permission.RegisterPermission(PermissionGiveKitAll, this); permission.RegisterPermission(PermissionGiveKitTo, this); permission.RegisterPermission(PermissionBypassBlacklist, this); AddLocalizedCommand(nameof(CommandGive)); AddCovalenceCommand(new[] { "inventory.give", "inventory.giveid", "giveid" }, nameof(CommandGive)); AddLocalizedCommand(nameof(CommandGiveAll)); AddCovalenceCommand("inventory.giveall", nameof(CommandGiveAll)); AddLocalizedCommand(nameof(CommandGiveAll)); #if REIGNOFKINGS || RUST AddCovalenceCommand("inventory.givearm", nameof(CommandGiveArm)); #endif AddLocalizedCommand(nameof(CommandGiveTo)); AddCovalenceCommand("inventory.giveto", nameof(CommandGiveTo)); AddLocalizedCommand(nameof(CommandGiveKit)); AddCovalenceCommand("inventory.givekit", nameof(CommandGiveKit)); AddLocalizedCommand(nameof(CommandGiveKitAll)); AddCovalenceCommand("inventory.givekitall", nameof(CommandGiveKitAll)); AddLocalizedCommand(nameof(CommandGiveKitTo)); AddCovalenceCommand("inventory.givekitto", nameof(CommandGiveKitTo)); } #endregion Initialization #region Item Giving #if HURTWORLD private T GetObjectByGuid(string guid) where T : UnityEngine.Object { HurtAssetDatabaseRecord databaseRecord; if (RuntimeHurtDB.Instance._objectDatabase.TryGetValue(guid, out databaseRecord)) { return databaseRecord.Object as T; } return null; } private ItemGeneratorAsset FindItem(string itemNameOrId) { ItemGeneratorAsset item; int itemId; if (int.TryParse(itemNameOrId, out itemId)) { item = GetItemGeneratorAsset(null, itemId); } else { item = GetObjectByGuid(itemNameOrId); if (item == null) { item = GetItemGeneratorAsset(itemNameOrId); } } return item; } private ItemGeneratorAsset GetItemGeneratorAsset(string itemName, int itemId = -1) { foreach (KeyValuePair itemGenerator in GlobalItemManager.Instance.GetGenerators()) { if (itemId != -1 && itemGenerator.Value.GeneratorId == itemId) { return itemGenerator.Value; } if (itemName != null && (itemName == itemGenerator.Value.DataProvider.NameKey || itemGenerator.Value.DataProvider.NameKey.ToLower().Contains(itemName))) { return itemGenerator.Value; } } return null; } #elif RUST private ItemDefinition FindItem(string itemNameOrId) { ItemDefinition itemDef = ItemManager.FindItemDefinition(itemNameOrId.ToLower()); if (itemDef == null) { int itemId; if (int.TryParse(itemNameOrId, out itemId)) { itemDef = ItemManager.FindItemDefinition(itemId); } } return itemDef; } #endif private object GiveItem(IPlayer player, string itemNameOrId, int amount = 1, string container = "main", float condition = 1f, ulong skinId = 0uL) { if (!player.IsConnected) { return false; } if (_config.ItemBlacklist.Contains(itemNameOrId, StringComparer.OrdinalIgnoreCase) && !player.HasPermission(PermissionBypassBlacklist)) { return null; } string itemName = itemNameOrId; #if SEVENDAYSTODIE EntityPlayer entityPlayer = player.Object as EntityPlayer; if (entityPlayer == null) { return false; } ItemValue itemValue = ItemClass.GetItem(itemName, true); if (itemValue.type == ItemValue.None.type) { return null; } ClientInfo clientInfo = ConsoleHelper.ParseParamEntityIdToClientInfo(entityPlayer.entityId.ToString()); if (clientInfo != null) { if (!entityPlayer.IsSpawned() || entityPlayer.IsDead()) { return false; } EntityItem entityItem = (EntityItem)EntityFactory.CreateEntity(new EntityCreationData { entityClass = EntityClass.FromString("item"), id = EntityFactory.nextEntityID++, itemStack = new ItemStack(new ItemValue(itemValue.type, 6, 6), amount), pos = entityPlayer.position, rot = new Vector3(20f, 0f, 20f), lifetime = 60f, belongsPlayerId = clientInfo.entityId }); GameManager.Instance.World.SpawnEntityInWorld(entityItem); clientInfo.SendPackage(NetPackageManager.GetPackage().Setup(entityItem.entityId, clientInfo.entityId)); GameManager.Instance.World.RemoveEntity(entityItem.entityId, EnumRemoveEntityReason.Despawned); itemName = itemValue.ItemClass.GetLocalizedItemName() ?? itemValue.ItemClass.Name; } #elif HURTWORLD ItemGeneratorAsset generator = FindItem(itemName.ToLower()); if (generator == null) { return null; } PlayerSession session = player.Object as PlayerSession; if (session == null) { return false; } PlayerInventory inventory = session.WorldPlayerEntity.GetComponent(); ItemObject itemObj; for (int i = 0; amount > 0 && (amount <= generator.DataProvider.MaxStackSize || generator.DataProvider.MaxStackSize <= amount); i++) { itemObj = GlobalItemManager.Instance.CreateItem(generator, generator.DataProvider.MaxStackSize < amount ? generator.DataProvider.MaxStackSize : amount); if (!inventory.GiveItemServer(itemObj)) { GlobalItemManager.SpawnWorldItem(itemObj, inventory); } amount -= generator.DataProvider.MaxStackSize < amount ? generator.DataProvider.MaxStackSize : amount; } #elif REIGNOFKINGS Player rokPlayer = player.Object as Player; if (rokPlayer == null) { return false; } Container itemContainer; switch (container.ToLower()) { case "belt": itemContainer = rokPlayer.CurrentCharacter.Entity.GetContainerOfType(CollectionTypes.Hotbar); break; default: itemContainer = rokPlayer.CurrentCharacter.Entity.GetContainerOfType(CollectionTypes.Inventory); break; } InvItemBlueprint blueprint = InvDefinitions.Instance.Blueprints.GetBlueprintForName(itemName, true, true); if (blueprint == null) { return null; } ContainerManagement containerManagement = blueprint.TryGet(); int stackableAmount = containerManagement != null ? containerManagement.StackLimit : 0; int amountGiven = 0; while (amountGiven < amount) { int amountToGive = Mathf.Min(stackableAmount, amount - amountGiven); InvGameItemStack itemStack = new InvGameItemStack(blueprint, amountToGive, null); if (!ItemCollection.AutoMergeAdd(itemContainer.Contents, itemStack)) { int stackAmount = amountToGive - itemStack.StackAmount; if (stackAmount != 0) { amountGiven += stackAmount; } else { break; } } else { amountGiven += amountToGive; } if (itemContainer.Contents.FreeSlotCount == 0) { break; } } #elif RUST Item item = ItemManager.Create(FindItem(itemNameOrId), amount, skinId); if (item == null) { return null; } BasePlayer basePlayer = player.Object as BasePlayer; if (basePlayer == null) { return false; } ItemContainer itemContainer = null; switch (container.ToLower()) { case "belt": itemContainer = basePlayer.inventory.containerBelt; break; default: itemContainer = basePlayer.inventory.containerMain; break; } item.amount = amount; item.conditionNormalized = condition; item.OnVirginSpawn(); if (!item.MoveToContainer(itemContainer) && !basePlayer.inventory.GiveItem(item)) { item.Remove(); return false; } itemName = item.info.displayName.english; if (_config.ShowPopupNotices) { player.Command("note.inv", item.info.itemid, amount); player.Command("gametip.showgametip", GetLang("ItemReceived", player.Id, itemName, amount)); timer.Once(2f, () => player.Command("gametip.hidegametip")); } #endif if (_config.ShowChatNotices) { Message(player, "ItemReceived", itemName, amount); } if (_config.LogToConsole) { Log($"{player.Name} {amount} x {itemName}"); } return true; } private void CommandGive(IPlayer player, string command, string[] args) { if (!player.HasPermission(PermissionGive)) { Message(player, "NotAllowed", command); return; } if (args.Length < 1) { Message(player, "UsageGive", command); return; } if (player.IsServer) { Message(player, "PlayersOnly", command); return; } int amount = args.Length >= 2 && int.TryParse(args[1], out amount) ? amount : 1; float condition = args.Length >= 3 && float.TryParse(args[2], out condition) ? condition : 1f; // Currently only Rust ulong skinId = args.Length >= 4 && ulong.TryParse(args[3], out skinId) ? skinId : 0uL; // Currently only Rust object giveItem = GiveItem(player, args[0], amount, condition: condition, skinId: skinId); if (giveItem == null) { Message(player, "InvalidItem", args[0]); } else if (!(bool)giveItem) { Message(player, "GiveFail", args[0], amount); } else { Message(player, "GiveSuccess", args[0], amount); } } private void CommandGiveTo(IPlayer player, string command, string[] args) { if (!player.HasPermission(PermissionGiveTo)) { Message(player, "NotAllowed", command); return; } if (args.Length < 2) { Message(player, "UsageGiveTo", command); return; } IPlayer target = FindPlayer(args[0], player); if (target == null) { target = player; if (target.IsServer) { Message(player, "PlayersOnly", command); return; } } int amount = args.Length >= 3 && int.TryParse(args[2], out amount) ? amount : 1; ulong skinId = args.Length >= 4 && ulong.TryParse(args[3], out skinId) ? skinId : 0uL; // Currently only Rust object giveItem = GiveItem(target, args[1], amount, skinId: skinId); if (giveItem == null) { Message(player, "InvalidItem", args[1]); } else if (!(bool)giveItem) { Message(player, "GiveToFail", args[1], amount, target.Name); } else { Message(player, "GiveToSuccess", args[1], amount, target.Name); } } private void CommandGiveAll(IPlayer player, string command, string[] args) { if (!player.HasPermission(PermissionGiveAll)) { Message(player, "NotAllowed", command); return; } if (args.Length < 1) { Message(player, "UsageGive", command); return; } if (!players.Connected.Any()) { Message(player, "NoPlayersConnected"); return; } int itemsGiven = 0; int connectedPlayers = 0; int amount = args.Length >= 2 && int.TryParse(args[1], out amount) ? amount : 1; ulong skinId = args.Length >= 3 && ulong.TryParse(args[2], out skinId) ? skinId : 0uL; // Currently only Rust foreach (IPlayer target in players.Connected.ToArray()) { object itemGiven = GiveItem(target, args[0], amount, skinId: skinId); if (itemGiven is bool && (bool)itemGiven) { itemsGiven++; connectedPlayers++; } } Message(player, itemsGiven > 0 ? "GiveAllSuccess" : "GiveAllFail", args[0], amount, connectedPlayers); } #if REIGNOFKINGS || RUST private void CommandGiveArm(IPlayer player, string command, string[] args) { if (!player.HasPermission(PermissionGiveArm)) { Message(player, "NotAllowed", command); return; } if (args.Length < 1) { Message(player, "UsageGiveArm", command); return; } int amount = args.Length >= 2 && int.TryParse(args[1], out amount) ? amount : 1; ulong skinId = args.Length >= 3 && ulong.TryParse(args[2], out skinId) ? skinId : 0uL; // Currently only Rust object giveItem = GiveItem(player, args[0], amount, "belt", skinId: skinId); if (giveItem == null) { Message(player, "InvalidItem", args[0]); } else if (!(bool)giveItem) { Message(player, "GiveFail", args[0], amount); } else { Message(player, "GiveSuccess", args[0], amount); } } #endif #endregion Item Giving #region Kit Giving private bool TryGiveKit(IPlayer player, string kitName) { if (!Kits.Call("isKit", kitName)) { Message(player, "InvalidKit", kitName); return false; } if (!player.IsConnected) { Message(player, "PlayerNotConnected", player.Name, player.Id); return false; } bool giveKit = false; #if HURTWORLD giveKit = Kits.Call("GiveKit", player.Object as PlayerSession, kitName); #elif REIGNOFKINGS giveKit = Kits.Call("GiveKit", player.Object as Player, kitName); #elif RUST object kitGiven = Kits.Call("GiveKit", player.Object as BasePlayer, kitName); giveKit = kitGiven is bool ? (bool)kitGiven : kitGiven == null; #elif SEVENDAYSTODIE giveKit = Kits.Call("GiveKit", player.Object as EntityAlive, kitName); #endif return giveKit; } private void CommandGiveKit(IPlayer player, string command, string[] args) { if (Kits == null || !Kits.IsLoaded) { Message(player, "KitsUnavailable"); return; } if (!player.HasPermission(PermissionGiveKit)) { Message(player, "NotAllowed", command); return; } if (args.Length < 1) { Message(player, "UsageGiveKit", command); return; } if (player.IsServer) { Message(player, "PlayersOnly", command); return; } bool kitGiven = TryGiveKit(player, args[0]); Message(player, kitGiven ? "GiveKitSuccess" : "GiveKitFail", args[0]); } private void CommandGiveKitTo(IPlayer player, string command, string[] args) { if (Kits == null || !Kits.IsLoaded) { Message(player, "KitsUnavailable"); return; } if (!player.HasPermission(PermissionGiveKitTo)) { Message(player, "NotAllowed", command); return; } if (args.Length < 2) { Message(player, "UsageGiveKitTo", command); return; } IPlayer target = FindPlayer(args[0], player); if (target != null) { bool kitGiven = TryGiveKit(target, args[1]); Message(player, kitGiven ? "GiveKitToSuccess" : "GiveKitToFail", args[1], target.Name); } } private void CommandGiveKitAll(IPlayer player, string command, string[] args) { if (Kits == null || !Kits.IsLoaded) { Message(player, "KitsUnavailable"); return; } if (!player.HasPermission(PermissionGiveKitAll)) { Message(player, "NotAllowed", command); return; } if (args.Length < 1) { Message(player, "UsageGiveKitAll", command); return; } if (!Kits.Call("isKit", args[0])) { Message(player, "InvalidKit", args[0]); return; } if (!players.Connected.Any()) { Message(player, "NoPlayersConnected"); return; } int kitsGiven = 0; int connectedPlayers = 0; foreach (IPlayer target in players.Connected.ToArray()) { if (TryGiveKit(target, args[0])) { kitsGiven++; connectedPlayers++; } } Message(player, kitsGiven > 0 ? "GiveKitAllSuccess" : "GiveKitAllFail", args[0], connectedPlayers); } #endregion Kit Giving #region Helpers private void AddLocalizedCommand(string command) { foreach (string language in lang.GetLanguages(this)) { foreach (KeyValuePair message in lang.GetMessages(language, this)) { if (message.Key.Equals(command) && !string.IsNullOrEmpty(message.Value)) { AddCovalenceCommand(message.Value, command); } } } } private IPlayer FindPlayer(string playerNameOrId, IPlayer player) { IPlayer[] foundPlayers = players.FindPlayers(playerNameOrId).ToArray(); if (foundPlayers.Length > 1) { Message(player, "PlayersFound", string.Join(", ", foundPlayers.Select(p => p.Name).Take(10).ToArray()).Truncate(60)); return null; } IPlayer target = foundPlayers.Length == 1 ? foundPlayers[0] : null; if (target == null) { Message(player, "NoPlayersFound", playerNameOrId); return null; } return target; } private string GetLang(string langKey, string playerId = null, params object[] args) { return string.Format(lang.GetMessage(langKey, this, playerId), args); } private void Message(IPlayer player, string textOrLang, params object[] args) { if (player.IsConnected) { string message = GetLang(textOrLang, player.Id, args); player.Reply(message != textOrLang ? message : textOrLang); } } #endregion Helpers } }