C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//#define DEBUG
using System;
using System.Collections.Generic;
using ConVar;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Auto Pickup", "Arainrr", "1.2.16")]
[Description("Automatically pickup hemp, pumpkin, ore, pickupable items, corpse, etc.")]
public class AutoPickup : RustPlugin
{
#region Fields
[PluginReference] private readonly Plugin Friends, Clans;
private static AutoPickup instance;
private static PickupType enabledPickupTypes;
private static object False;
private const string PERMISSION_USE = "autopickup.use";
[Flags]
//[JsonConverter(typeof(StringEnumConverter))]
private enum PickupType
{
None = 0,
PlantEntity = 1,
CollectibleEntity = 1 << 1,
MurdererCorpse = 1 << 2,
ScientistCorpse = 1 << 3,
PlayerCorpse = 1 << 4,
ItemDropBackpack = 1 << 5,
ItemDrop = 1 << 6,
WorldItem = 1 << 7,
LootContainer = 1 << 8,
CollectableGifts = 1 << 9,
}
#endregion Fields
#region Oxide Hooks
private void Init()
{
LoadData();
False = false;
instance = this;
enabledPickupTypes = PickupType.None;
Unsubscribe(nameof(CanLootEntity));
Unsubscribe(nameof(OnPlayerAttack));
Unsubscribe(nameof(OnEntitySpawned));
permission.RegisterPermission(PERMISSION_USE, this);
cmd.AddChatCommand(configData.chatS.command, this, nameof(CmdAutoPickup));
}
private void OnServerInitialized()
{
UpdateConfig();
foreach (var entry in configData.autoPickupS)
{
if (entry.Value.enabled)
{
enabledPickupTypes |= entry.Key;
}
}
if (enabledPickupTypes.HasFlag(PickupType.LootContainer))
{
bool enabledBarrel = false, enabledLoot = false;
foreach (var entry in configData.lootContainerS)
{
if (!entry.Value) continue;
if (IsBarrel(entry.Key))
{
enabledBarrel = true;
}
else
{
enabledLoot = true;
}
}
if (enabledBarrel)
{
Subscribe(nameof(OnPlayerAttack));
}
if (enabledLoot)
{
Subscribe(nameof(CanLootEntity));
}
}
Subscribe(nameof(OnEntitySpawned));
foreach (var baseNetworkable in BaseNetworkable.serverEntities)
{
CheckEntity(baseNetworkable);
}
}
private void OnServerSave() => timer.Once(UnityEngine.Random.Range(0f, 60f), SaveData);
private void Unload()
{
if (AutoPickupHelper.autoPickupHelpers != null)
{
foreach (var autoPickupEntity in AutoPickupHelper.autoPickupHelpers.ToArray())
{
UnityEngine.Object.Destroy(autoPickupEntity);
}
AutoPickupHelper.autoPickupHelpers = null;
}
foreach (var player in BasePlayer.activePlayerList)
{
DestroyUI(player);
}
SaveData();
configData = null;
False = instance = null;
}
private void OnPlayerAttack(BasePlayer attacker, HitInfo info)
{
if (attacker == null || !attacker.userID.IsSteamId()) return;
var barrel = info?.HitEntity as LootContainer;
if (barrel == null || barrel.net == null) return;
if (!IsBarrel(barrel.ShortPrefabName)) return;
var radius = configData.autoPickupS[PickupType.LootContainer].radius;
if (radius > 0f && Vector3.Distance(attacker.transform.position, barrel.transform.position) > radius)
{
return;
}
if (permission.UserHasPermission(attacker.UserIDString, PERMISSION_USE))
{
if (TryPickupLootContainer(barrel, attacker, info))
{
}
}
}
private object CanLootEntity(BasePlayer player, LootContainer lootContainer)
{
if (player == null || lootContainer == null) return null;
if (permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
{
if (TryPickupLootContainer(lootContainer, player))
{
return False;
}
}
return null;
}
private void OnEntitySpawned(BaseNetworkable baseNetworkable) => CheckEntity(baseNetworkable, true);
#endregion Oxide Hooks
#region Methods
private bool TryPickupLootContainer(LootContainer lootContainer, BasePlayer player, HitInfo info = null)
{
bool enabled;
if (configData.lootContainerS.TryGetValue(lootContainer.ShortPrefabName, out enabled) && !enabled)
{
return false;
}
if (configData.globalS.preventPickupLoot && lootContainer.OwnerID.IsSteamId() && !AreFriends(lootContainer.OwnerID, player.userID))
{
return false;
}
var autoPickData = GetAutoPickupData(player.userID, true);
if (autoPickData.enabled && !autoPickData.blockPickupTypes.HasFlag(PickupType.LootContainer))
{
if (CanAutoPickup(player, lootContainer) && PickupLootContainer(player, lootContainer, info))
{
return true;
}
}
return false;
}
private void UpdateConfig()
{
foreach (PickupType pickupType in Enum.GetValues(typeof(PickupType)))
{
if (pickupType == PickupType.None) continue;
if (!configData.autoPickupS.ContainsKey(pickupType))
{
configData.autoPickupS.Add(pickupType, new ConfigData.PickupTypeS { enabled = true, radius = 0.5f });
}
}
foreach (var itemDefinition in ItemManager.GetItemDefinitions())
{
if (!configData.worldItemS.itemCategoryS.ContainsKey(itemDefinition.category))
{
configData.worldItemS.itemCategoryS.Add(itemDefinition.category, true);
}
}
foreach (var prefab in GameManifest.Current.entities)
{
var entity = GameManager.server.FindPrefab(prefab.ToLower())?.GetComponent<BaseEntity>();
if (entity == null || string.IsNullOrEmpty(entity.ShortPrefabName)) continue;
var lootContainer = entity as LootContainer;
if (lootContainer != null)
{
if (!configData.lootContainerS.ContainsKey(lootContainer.ShortPrefabName))
{
configData.lootContainerS.Add(lootContainer.ShortPrefabName, !lootContainer.ShortPrefabName.Contains("stocking"));
}
continue;
}
var collectibleEntity = entity as CollectibleEntity;
if (collectibleEntity != null)
{
if (!configData.collectibleEntityS.ContainsKey(collectibleEntity.ShortPrefabName))
{
configData.collectibleEntityS.Add(collectibleEntity.ShortPrefabName, true);
}
continue;
}
var plantEntity = entity as GrowableEntity;
if (plantEntity != null)
{
if (!configData.plantEntityS.ContainsKey(plantEntity.ShortPrefabName))
{
configData.plantEntityS.Add(plantEntity.ShortPrefabName, true);
}
continue;
}
}
SaveConfig();
}
#region AreFriends
private bool AreFriends(ulong playerID, ulong friendID)
{
if (playerID == friendID) return true;
if (configData.globalS.useTeams && SameTeam(playerID, friendID)) return true;
if (configData.globalS.useFriends && HasFriend(playerID, friendID)) return true;
if (configData.globalS.useClans && SameClan(playerID, friendID)) return true;
return false;
}
private static bool SameTeam(ulong playerID, ulong friendID)
{
if (!RelationshipManager.TeamsEnabled()) return false;
var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerID);
if (playerTeam == null) return false;
var friendTeam = RelationshipManager.ServerInstance.FindPlayersTeam(friendID);
if (friendTeam == null) return false;
return playerTeam == friendTeam;
}
private bool HasFriend(ulong playerID, ulong friendID)
{
if (Friends == null) return false;
return (bool)Friends.Call("HasFriend", playerID, friendID);
}
private bool SameClan(ulong playerID, ulong friendID)
{
if (Clans == null) return false;
//Clans
var isMember = Clans.Call("IsClanMember", playerID.ToString(), friendID.ToString());
if (isMember != null) return (bool)isMember;
//Rust:IO Clans
var playerClan = Clans.Call("GetClanOf", playerID);
if (playerClan == null) return false;
var friendClan = Clans.Call("GetClanOf", friendID);
if (friendClan == null) return false;
return (string)playerClan == (string)friendClan;
}
#endregion AreFriends
#region Data
private StoredData.AutoPickData defaultData;
private StoredData.AutoPickData DefaultData => defaultData ?? (defaultData = CreateDefaultData());
private StoredData.AutoPickData GetAutoPickupData(ulong playerID, bool readOnly = false)
{
StoredData.AutoPickData autoPickData;
if (!storedData.playerAutoPickupData.TryGetValue(playerID, out autoPickData))
{
if (readOnly)
{
return DefaultData;
}
autoPickData = CreateDefaultData();
storedData.playerAutoPickupData.Add(playerID, autoPickData);
}
return autoPickData;
}
private StoredData.AutoPickData CreateDefaultData()
{
return new StoredData.AutoPickData
{
enabled = configData.globalS.defaultEnabled
};
}
#endregion Data
#endregion Methods
#region Helpers
private static void CheckEntity(BaseNetworkable baseNetworkable, bool justCreated = false)
{
if (baseNetworkable == null) return;
var pickupType = GetPickupTypeFromEntity(baseNetworkable);
if (pickupType == PickupType.None) return;
if (!enabledPickupTypes.HasFlag(pickupType))
{
return;
}
var autoPickupEntity = baseNetworkable.GetComponent<AutoPickupHelper>();
if (autoPickupEntity != null)
{
UnityEngine.Object.Destroy(autoPickupEntity);
}
switch (pickupType)
{
case PickupType.CollectibleEntity:
{
bool enabled;
if (configData.collectibleEntityS.TryGetValue(baseNetworkable.ShortPrefabName, out enabled) && !enabled)
{
return;
}
break;
}
case PickupType.PlantEntity:
{
bool enabled;
if (configData.plantEntityS.TryGetValue(baseNetworkable.ShortPrefabName, out enabled) && !enabled)
{
return;
}
if (configData.globalS.preventPlanterBox && baseNetworkable.GetParentEntity() is PlanterBox)
{
return;
}
break;
}
case PickupType.MurdererCorpse:
case PickupType.ScientistCorpse:
case PickupType.PlayerCorpse:
case PickupType.ItemDrop:
case PickupType.ItemDropBackpack:
break;
case PickupType.WorldItem:
{
var worldItem = baseNetworkable as WorldItem;
if (worldItem != null)
{
var item = worldItem.GetItem();
if (item != null)
{
if (configData.worldItemS.itemBlockList.Contains(item.info.shortname)) return;
bool enabled;
if (configData.worldItemS.itemCategoryS.TryGetValue(item.info.category, out enabled) && !enabled)
{
return;
}
}
}
if (justCreated)
{
var collisionDetection = baseNetworkable.GetComponent<WorldItemCollisionDetection>();
if (collisionDetection != null)
{
UnityEngine.Object.Destroy(collisionDetection);
}
baseNetworkable.gameObject.AddComponent<WorldItemCollisionDetection>();
return;
}
break;
}
}
CreateAutoPickupHelper(baseNetworkable.transform, pickupType);
}
private static PickupType GetPickupTypeFromEntity(BaseNetworkable baseNetworkable)
{
switch (baseNetworkable.ShortPrefabName)
{
case "murderer_corpse": return PickupType.MurdererCorpse;
case "scientist_corpse": return PickupType.ScientistCorpse;
case "player_corpse": return PickupType.PlayerCorpse;
case "item_drop": return PickupType.ItemDrop;
case "item_drop_backpack": return PickupType.ItemDropBackpack;
default:
if (baseNetworkable is GrowableEntity)
{
return PickupType.PlantEntity;
}
if (baseNetworkable is CollectibleEntity)
{
return PickupType.CollectibleEntity;
}
if (baseNetworkable is WorldItem)
{
return PickupType.WorldItem;
}
if (baseNetworkable is CollectableEasterEgg)
{
return PickupType.CollectableGifts;
}
return PickupType.None;
}
}
private static void CreateAutoPickupHelper(Transform transform, PickupType pickupType)
{
var newObject = new GameObject("AutoPickHelper");
newObject.transform.SetParent(transform);
newObject.transform.position = transform.position;
newObject.AddComponent<AutoPickupHelper>().Init(pickupType);
}
private static bool PickupLootContainer(BasePlayer player, LootContainer lootContainer, HitInfo info = null)
{
var itemContainer = lootContainer?.inventory;
if (itemContainer != null)
{
for (int i = itemContainer.itemList.Count - 1; i >= 0; i--)
{
player.GiveItem(itemContainer.itemList[i], BaseEntity.GiveItemReason.PickedUp);
}
if (itemContainer.itemList == null || itemContainer.itemList.Count <= 0)
{
if (info != null)
{
lootContainer.Invoke(() => lootContainer.Die(info), 0.2f);
}
else
{
lootContainer.Invoke(() => lootContainer.Kill(BaseNetworkable.DestroyMode.Gib), 0.2f);
}
}
return true;
}
return false;
}
private static bool InventoryExistItem(BasePlayer player, Item item)
{
return player.inventory.containerMain.FindItemByItemID(item.info.itemid) != null
|| player.inventory.containerBelt.FindItemByItemID(item.info.itemid) != null;
}
private static bool InventoryIsFull(BasePlayer player, Item item)
{
if (player.inventory.containerMain.IsFull() && player.inventory.containerBelt.IsFull())
{
var item1 = player.inventory.containerMain.FindItemByItemID(item.info.itemid);
var item2 = player.inventory.containerBelt.FindItemByItemID(item.info.itemid);
return (item1 == null || !item.CanStack(item1)) && (item2 == null || !item.CanStack(item2));
}
return false;
}
private static bool PickupDroppedItemContainer(BasePlayer player, DroppedItemContainer droppedItemContainer)
{
var itemContainer = droppedItemContainer?.inventory;
if (itemContainer != null)
{
for (int i = itemContainer.itemList.Count - 1; i >= 0; i--)
{
player.GiveItem(itemContainer.itemList[i], BaseEntity.GiveItemReason.PickedUp);
}
if (itemContainer.itemList == null || itemContainer.itemList.Count <= 0)
{
droppedItemContainer.Kill(BaseNetworkable.DestroyMode.Gib);
}
return true;
}
return false;
}
private static bool PickupPlayerCorpse(BasePlayer player, PlayerCorpse playerCorpse)
{
var itemContainers = playerCorpse?.containers;
if (itemContainers != null)
{
for (int i = itemContainers.Length - 1; i >= 0; i--)
{
var itemContainer = itemContainers[i];
if (itemContainer != null)
{
for (int j = itemContainer.itemList.Count - 1; j >= 0; j--)
{
player.GiveItem(itemContainer.itemList[j], BaseEntity.GiveItemReason.PickedUp);
}
}
}
return true;
}
return false;
}
private static bool CanAutoPickup(BasePlayer player, BaseEntity entity)
{
return entity != null && player.CanInteract() && Interface.CallHook("OnAutoPickupEntity", player, entity) == null;
}
private static bool IsBarrel(string shortPrefabName) => shortPrefabName.Contains("barrel") || shortPrefabName.Contains("roadsign");
#endregion Helpers
#region Components
private class WorldItemCollisionDetection : MonoBehaviour
{
private bool collided;
private void OnCollisionEnter(Collision collision)
{
if (collided || collision?.gameObject == null) return;
collided = true;
Invoke(nameof(AddAutoPickupComponent), configData.worldItemS.pickupDelay);
}
private void AddAutoPickupComponent()
{
CreateAutoPickupHelper(transform, PickupType.WorldItem);
DestroyImmediate(this);
}
}
private class AutoPickupHelper : FacepunchBehaviour
{
private const int LAYER_PLAYER = (int)Rust.Layer.Player_Server;
public static List<AutoPickupHelper> autoPickupHelpers;
private BaseEntity entity;
private PickupType pickupType;
private SphereCollider sphereCollider;
private void Awake()
{
if (autoPickupHelpers == null)
{
autoPickupHelpers = new List<AutoPickupHelper>();
}
autoPickupHelpers.Add(this);
entity = GetComponentInParent<BaseEntity>();
}
public void Init(PickupType pickupType)
{
if (gameObject == null || entity == null)
{
Destroy(this);
return;
}
this.pickupType = pickupType;
transform.position = entity.CenterPoint();
CreateCollider();
}
private void CreateCollider()
{
sphereCollider = gameObject.AddComponent<SphereCollider>();
sphereCollider.gameObject.layer = (int)Rust.Layer.Reserved1;
sphereCollider.radius = configData.autoPickupS[pickupType].radius;
sphereCollider.isTrigger = true;
#if DEBUG
InvokeRepeating(Tick, 0f, 1f);
#endif
}
#if DEBUG
private void Tick()
{
foreach (var player in BasePlayer.activePlayerList)
{
if (player.IsAdmin && Vector3.Distance(transform.position, player.transform.position) < 50f)
{
player.SendConsoleCommand("ddraw.sphere", 1, Color.cyan, sphereCollider.transform.position, sphereCollider.radius);
}
}
}
#endif
private void OnTriggerEnter(Collider collider)
{
if (collider == null || collider.gameObject == null) return;
if (collider.gameObject.layer != LAYER_PLAYER) return;
var player = collider.ToBaseEntity() as BasePlayer;
if (player == null || !player.userID.IsSteamId()) return;
if (instance.permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
{
var autoPickData = instance.GetAutoPickupData(player.userID, true);
if (autoPickData.enabled && !autoPickData.blockPickupTypes.HasFlag(pickupType))
{
switch (pickupType)
{
case PickupType.PlantEntity:
var plantEntity = entity as GrowableEntity;
if (configData.globalS.preventPickupPlant && plantEntity.OwnerID.IsSteamId() && !instance.AreFriends(plantEntity.OwnerID, player.userID)) return;
if (CanAutoPickup(player, plantEntity))
{
if (autoPickData.autoClone)
{
plantEntity.TakeClones(player);
}
else
{
plantEntity.PickFruit(player);
}
plantEntity.RemoveDying(player);
}
return;
case PickupType.CollectibleEntity:
var collectibleEntity = entity as CollectibleEntity;
if (CanAutoPickup(player, collectibleEntity))
{
collectibleEntity.DoPickup(player);
Destroy(this);
}
return;
case PickupType.ItemDrop:
case PickupType.ItemDropBackpack:
var droppedItemContainer = entity as DroppedItemContainer;
if (configData.globalS.preventPickupBackpack && droppedItemContainer.playerSteamID.IsSteamId() && !instance.AreFriends(droppedItemContainer.playerSteamID, player.userID)) return;
if (CanAutoPickup(player, droppedItemContainer))
{
if (PickupDroppedItemContainer(player, droppedItemContainer))
{
Destroy(this);
}
}
return;
case PickupType.MurdererCorpse:
case PickupType.ScientistCorpse:
case PickupType.PlayerCorpse:
var playerCorpse = entity as PlayerCorpse;
if (!playerCorpse.CanLoot()) return;
if (configData.globalS.preventPickupCorpse && playerCorpse.playerSteamID.IsSteamId() && !instance.AreFriends(playerCorpse.playerSteamID, player.userID)) return;
if (CanAutoPickup(player, playerCorpse))
{
if (PickupPlayerCorpse(player, playerCorpse))
{
Destroy(this);
}
}
return;
case PickupType.WorldItem:
var worldItem = entity as WorldItem;
if (CanAutoPickup(player, worldItem))
{
var item = worldItem.GetItem();
if (item != null)
{
if (configData.worldItemS.onlyPickupExistItem && !InventoryExistItem(player, item)) return;
if (configData.worldItemS.checkInventoryFull && InventoryIsFull(player, item)) return;
var rpcMessage = default(BaseEntity.RPCMessage);
rpcMessage.player = player;
worldItem.Pickup(rpcMessage);
Destroy(this);
}
}
return;
case PickupType.CollectableGifts:
var gifts = entity as CollectableEasterEgg;
if (CanAutoPickup(player, gifts))
{
if (configData.collectableGiftsS.requiresBasket && !(player.GetHeldEntity() is EasterBasket)) return;
if (EggHuntEvent.serverEvent != null)
{
if (!EggHuntEvent.serverEvent.IsEventActive())
{
return;
}
EggHuntEvent.serverEvent.OnEggCollected(player, gifts);
player.GiveItem(ItemManager.Create(gifts.itemToGive));
}
Effect.server.Run(gifts.pickupEffect.resourcePath, base.transform.position + Vector3.up * 0.3f, Vector3.up);
gifts.Kill();
Destroy(this);
}
return;
default:
return;
}
}
}
}
private void OnDestroy()
{
Destroy(gameObject);
autoPickupHelpers?.Remove(this);
}
}
#endregion Components
#region UI
private const string UINAME_MAIN = "AutoPickupUI_Main";
private const string UINAME_MENU = "AutoPickupUI_Menu";
private static void CreateMainUI(BasePlayer player)
{
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0" },
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-180 -180", OffsetMax = "180 230" },
CursorEnabled = true
}, "Hud", UINAME_MAIN);
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0.6" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
}, UINAME_MAIN);
var titlePanel = container.Add(new CuiPanel
{
Image = { Color = "0.31 0.88 0.71 1" },
RectTransform = { AnchorMin = "0 0.912", AnchorMax = "0.998 1" },
}, UINAME_MAIN);
container.Add(new CuiElement
{
Parent = titlePanel,
Components =
{
new CuiTextComponent { Text = instance.Lang("Title", player.UserIDString), FontSize = 20, Align = TextAnchor.MiddleCenter, Color ="1 0 0 1" },
new CuiOutlineComponent { Distance = "0.5 0.5", Color = "1 1 1 1" },
new CuiRectTransformComponent { AnchorMin = "0.2 0", AnchorMax = "0.8 1" }
}
});
container.Add(new CuiButton
{
Button = { Color = "0.95 0.1 0.1 0.95", Close = UINAME_MAIN },
Text = { Text = "X", Align = TextAnchor.MiddleCenter, Color = "0 0 0 1", FontSize = 22 },
RectTransform = { AnchorMin = "0.885 0", AnchorMax = "1 0.99" }
}, titlePanel);
CuiHelper.DestroyUi(player, UINAME_MAIN);
CuiHelper.AddUi(player, container);
var autoPickData = instance.GetAutoPickupData(player.userID);
UpdateMenuUI(player, autoPickData);
}
private static void UpdateMenuUI(BasePlayer player, StoredData.AutoPickData autoPickData)
{
if (player == null) return;
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.4" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.898" },
}, UINAME_MAIN, UINAME_MENU);
int i = 0;
const float spacingY = 0.01f;
const float entrySize = (1f - 11f * spacingY) / 12f;
var enabledMsg = instance.Lang("Enabled", player.UserIDString);
var disabledMsg = instance.Lang("Disabled", player.UserIDString);
var anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntryUI(ref container, $"AutoPickupUI Toggle",
instance.Lang("Status", player.UserIDString),
autoPickData.enabled ? enabledMsg : disabledMsg,
$"0 {anchors[0]}", $"0.995 {anchors[1]}");
foreach (PickupType pickupType in Enum.GetValues(typeof(PickupType)))
{
if (pickupType == PickupType.None || !enabledPickupTypes.HasFlag(pickupType)) continue;
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntryUI(ref container, $"AutoPickupUI {pickupType}",
instance.Lang(pickupType.ToString(), player.UserIDString),
!autoPickData.blockPickupTypes.HasFlag(pickupType) ? enabledMsg : disabledMsg,
$"0 {anchors[0]}", $"0.995 {anchors[1]}");
if (pickupType == PickupType.PlantEntity && !autoPickData.blockPickupTypes.HasFlag(pickupType))
{
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntryUI(ref container, $"AutoPickupUI Clone",
instance.Lang("AutoClonePlants", player.UserIDString),
autoPickData.autoClone ? enabledMsg : disabledMsg,
$"0 {anchors[0]}", $"0.995 {anchors[1]}");
}
}
CuiHelper.DestroyUi(player, UINAME_MENU);
CuiHelper.AddUi(player, container);
}
private static void CreateEntryUI(ref CuiElementContainer container, string command, string leftText, string rightText, string anchorMin, string anchorMax)
{
var panelName = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.6" },
RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax },
}, UINAME_MENU);
container.Add(new CuiLabel
{
Text = { Color = "0 1 1 1", FontSize = 14, Align = TextAnchor.MiddleLeft, Text = leftText },
RectTransform = { AnchorMin = "0.06 0", AnchorMax = "0.795 1" }
}, panelName);
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0.7", Command = command },
Text = { Text = rightText, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FontSize = 14 },
RectTransform = { AnchorMin = "0.7 0.2", AnchorMax = "0.985 0.8" },
}, panelName);
}
private static float[] GetEntryAnchors(int i, float entrySize, float spacingY)
{
//return new[] { 1f - (i + 1) * spacing, 1f - i * spacing };
return new[] { 1f - (i + 1) * entrySize - i * spacingY, 1f - i * (entrySize + spacingY) };
}
private static void DestroyUI(BasePlayer player) => CuiHelper.DestroyUi(player, UINAME_MAIN);
#endregion UI
#region Commands
[ConsoleCommand("AutoPickupUI")]
private void CCmdAutoPickupUI(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) return;
var autoPickData = GetAutoPickupData(player.userID);
switch (arg.Args[0].ToLower())
{
case "toggle":
autoPickData.enabled = !autoPickData.enabled;
break;
case "clone":
autoPickData.autoClone = !autoPickData.autoClone;
break;
default:
PickupType pickupType;
if (Enum.TryParse(arg.Args[0], true, out pickupType))
{
if (autoPickData.blockPickupTypes.HasFlag(pickupType))
{
autoPickData.blockPickupTypes &= ~pickupType;
}
else
{
autoPickData.blockPickupTypes |= pickupType;
}
}
break;
}
UpdateMenuUI(player, autoPickData);
}
private void CmdAutoPickup(BasePlayer player, string command, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
{
Print(player, Lang("NotAllowed", player.UserIDString));
return;
}
CreateMainUI(player);
}
#endregion Commands
#region ConfigurationFile
private static ConfigData configData;
private class ConfigData
{
[JsonProperty(PropertyName = "Settings")]
public Settings globalS = new Settings();
[JsonProperty(PropertyName = "Chat Settings")]
public ChatS chatS = new ChatS();
[JsonProperty(PropertyName = "Auto Pickup Settings")]
public Dictionary<PickupType, PickupTypeS> autoPickupS = new Dictionary<PickupType, PickupTypeS>();
[JsonProperty(PropertyName = "World Item Pickup Settings")]
public WorldItemPickupS worldItemS = new WorldItemPickupS();
[JsonProperty(PropertyName = "Collectable Gifts Pickup Settings")]
public CollectableGiftsPickupS collectableGiftsS = new CollectableGiftsPickupS();
[JsonProperty(PropertyName = "Loot Container Pickup Settings")]
public Dictionary<string, bool> lootContainerS = new Dictionary<string, bool>();
[JsonProperty(PropertyName = "Collectible Entity Pickup Settings")]
public Dictionary<string, bool> collectibleEntityS = new Dictionary<string, bool>();
[JsonProperty(PropertyName = "Plant Entity Pickup Settings")]
public Dictionary<string, bool> plantEntityS = new Dictionary<string, bool>();
public class Settings
{
[JsonProperty(PropertyName = "Clear Data On Map Wipe")]
public bool clearDataOnWipe = false;
[JsonProperty(PropertyName = "Use Teams")]
public bool useTeams = false;
[JsonProperty(PropertyName = "Use Clans")]
public bool useClans = true;
[JsonProperty(PropertyName = "Use Friends")]
public bool useFriends = true;
[JsonProperty(PropertyName = "Auto pickup is enabled by default")]
public bool defaultEnabled = true;
[JsonProperty(PropertyName = "Prevent pickup other player's backpack")]
public bool preventPickupBackpack;
[JsonProperty(PropertyName = "Prevent pickup other player's corpse")]
public bool preventPickupCorpse;
[JsonProperty(PropertyName = "Prevent pickup other player's plant entity")]
public bool preventPickupPlant;
[JsonProperty(PropertyName = "Prevent pickup other player's loot container")]
public bool preventPickupLoot = true;
[JsonProperty(PropertyName = "Prevent pickup of plant entities in the planter box")]
public bool preventPlanterBox = false;
}
public class ChatS
{
[JsonProperty(PropertyName = "Chat Command")]
public string command = "ap";
[JsonProperty(PropertyName = "Chat Prefix")]
public string prefix = "<color=#00FFFF>[AutoPickup]</color>: ";
[JsonProperty(PropertyName = "Chat SteamID Icon")]
public ulong steamIDIcon = 0;
}
public class PickupTypeS
{
[JsonProperty(PropertyName = "Enabled")]
public bool enabled = true;
[JsonProperty(PropertyName = "Check Radius")]
public float radius = 0.5f;
}
public class WorldItemPickupS
{
[JsonProperty(PropertyName = "Auto Pickup Delay")]
public float pickupDelay = 0.5f;
[JsonProperty(PropertyName = "Check that player's inventory is full")]
public bool checkInventoryFull = true;
[JsonProperty(PropertyName = "Only pickup items that exist in player's inventory")]
public bool onlyPickupExistItem;
[JsonProperty(PropertyName = "Item Block List (Item shortname)")]
public HashSet<string> itemBlockList = new HashSet<string>();
[JsonProperty(PropertyName = "Allow Pickup Item Category")]
public Dictionary<ItemCategory, bool> itemCategoryS = new Dictionary<ItemCategory, bool>();
}
public class CollectableGiftsPickupS
{
[JsonProperty(PropertyName = "Requires player to hold a basket")]
public bool requiresBasket = true;
}
[JsonProperty(PropertyName = "Version")]
public VersionNumber version;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
configData = Config.ReadObject<ConfigData>();
if (configData == null)
{
LoadDefaultConfig();
}
else
{
UpdateConfigValues();
}
}
catch (Exception ex)
{
PrintError($"The configuration file is corrupted.\n{ex}");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
PrintWarning("Creating a new configuration file");
configData = new ConfigData();
configData.version = Version;
}
protected override void SaveConfig() => Config.WriteObject(configData);
private void UpdateConfigValues()
{
if (configData.version < Version)
{
if (configData.version <= default(VersionNumber))
{
string prefix, prefixColor;
if (GetConfigValue(out prefix, "Chat Settings", "Chat Prefix") && GetConfigValue(out prefixColor, "Chat Settings", "Chat Prefix Color"))
{
configData.chatS.prefix = $"<color={prefixColor}>{prefix}</color>: ";
}
}
if (configData.version <= new VersionNumber(1, 2, 13))
{
configData.autoPickupS[PickupType.LootContainer].radius = 0f;
}
configData.version = Version;
}
}
private bool GetConfigValue<T>(out T value, params string[] path)
{
var configValue = Config.Get(path);
if (configValue == null)
{
value = default(T);
return false;
}
value = Config.ConvertValue<T>(configValue);
return true;
}
#endregion ConfigurationFile
#region DataFile
private StoredData storedData;
private class StoredData
{
public readonly Dictionary<ulong, AutoPickData> playerAutoPickupData = new Dictionary<ulong, AutoPickData>();
public class AutoPickData
{
public bool enabled;
public bool autoClone;
public PickupType blockPickupTypes;
}
}
private void LoadData()
{
try
{
storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
}
catch
{
storedData = null;
}
if (storedData == null)
{
ClearData();
}
}
private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);
private void ClearData()
{
storedData = new StoredData();
SaveData();
}
private void OnNewSave(string filename)
{
if (configData.globalS.clearDataOnWipe)
{
ClearData();
}
}
#endregion DataFile
#region LanguageFile
private void Print(BasePlayer player, string message)
{
Player.Message(player, message, configData.chatS.prefix, configData.chatS.steamIDIcon);
}
private string Lang(string key, string id = null, params object[] args)
{
try
{
return string.Format(lang.GetMessage(key, this, id), args);
}
catch (Exception)
{
PrintError($"Error in the language formatting of '{key}'.(userid: {id}.lang: {lang.GetLanguage(id)}.args: {string.Join(" ,", args)})");
throw;
}
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NotAllowed"] = "You do not have permission to use this command",
["Enabled"] = "<color=#8ee700>Enabled</color>",
["Disabled"] = "<color=#ce422b>Disabled</color>",
["Title"] = "Auto Pickup UI",
["Status"] = "Auto Pickup Status",
["PlantEntity"] = "Auto Pickup Plant Entity",
["CollectibleEntity"] = "Auto Pickup Collectible Entity",
["MurdererCorpse"] = "Auto Pickup Murderer Corpse",
["ScientistCorpse"] = "Auto Pickup Scientist Corpse",
["PlayerCorpse"] = "Auto Pickup Player Corpse",
["ItemDropBackpack"] = "Auto Pickup Item Drop Backpack",
["ItemDrop"] = "Auto Pickup Item Drop",
["WorldItem"] = "Auto Pickup World Item",
["LootContainer"] = "Auto Pickup Loot Container",
["CollectableGifts"] = "Auto Pickup Collectable Gifts",
["AutoClonePlants"] = "Auto Clone Plants",
}, this);
lang.RegisterMessages(new Dictionary<string, string>
{
["NotAllowed"] = "您没有使用该命令的权限",
["Enabled"] = "<color=#8ee700>已启用</color>",
["Disabled"] = "<color=#ce422b>已禁用</color>",
["Title"] = "自动拾取设置",
["Status"] = "自动拾取状态",
["PlantEntity"] = "自动拾取农作物",
["CollectibleEntity"] = "自动拾取收藏品",
["MurdererCorpse"] = "自动拾取僵尸尸体",
["ScientistCorpse"] = "自动拾取科学家尸体",
["PlayerCorpse"] = "自动拾取玩家尸体",
["ItemDropBackpack"] = "自动拾取尸体背包",
["ItemDrop"] = "自动拾取掉落容器",
["WorldItem"] = "自动拾取掉落物品",
["LootContainer"] = "自动拾取战利品容器",
["CollectableGifts"] = "自动拾取节日礼物",
["AutoClonePlants"] = "自动克隆植物",
}, this, "zh-CN");
}
#endregion LanguageFile
}
}