> c.reload Bank
Failed compiling 'Bank.cs'
1. The type or namespace name 'OnlinePlayersAttribute' could not be found (are you missing a using directive or an assembly reference?) [CS0246]
(Bank 10 line 340) I get this message in console.
[OnlinePlayers]
Hash<BasePlayer, OnlinePlayer> onlinePlayers = new Hash<BasePlayer, OnlinePlayer> ();
Dictionary<string, DateTime> bankCooldowns = new Dictionary<string, DateTime> (); //[OnlinePlayers]
Hash<BasePlayer, OnlinePlayer> onlinePlayers = new Hash<BasePlayer, OnlinePlayer> ();
Dictionary<string, DateTime> bankCooldowns = new Dictionary<string, DateTime> ();Merged post
> c.reload Bank
Unloaded plugin Bank v1.0.55 by Calytic
Bank v1.0.55 by Calytic hook 'Init' took longer than 100ms [652ms]
Loaded plugin Bank v1.0.55 by Calytic [109ms]Merged post
This version works now... test it and see
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Oxide.Plugins
{
[Info("Bank", "Calytic", "1.0.55")]
[Description("Safe player storage")]
class Bank : RustPlugin
{
#region Variables
string defaultBoxPrefab;
int defaultSlots;
Dictionary<string, object> boxPrefabs;
Dictionary<string, object> boxSlots;
bool keyring;
float cooldownMinutes;
bool npconly;
List<string> npcids = new List<string>();
float radiationMax;
bool allowSafeZone;
public static DataFileSystem datafile;
public static DataFileSystem configFile;
Dictionary<string, object> itemLimits = new Dictionary<string, object>();
[PluginReference]
Plugin MasterKey;
#endregion
#region Bank/Item Profile
public class ItemProfile
{
public string id;
public int amount;
public int slot;
public int capacity;
public Item.Flag flags;
public float condition;
public ulong skin;
public List<ItemProfile> contents;
public int primaryMagazine;
public int ammoType;
public int dataInt;
[JsonConstructor]
public ItemProfile(string id, int amount, int slot, int capacity, Item.Flag flags, float condition = 0.0f, ulong skin = 0, List<ItemProfile> contents = null, int primaryMagazine = 0, int ammoType = 0, int dataInt = 0)
{
this.id = id;
this.amount = amount;
this.slot = slot;
this.capacity = capacity;
this.flags = flags;
this.condition = condition;
this.skin = skin;
this.contents = contents;
this.primaryMagazine = primaryMagazine;
this.ammoType = ammoType;
this.dataInt = dataInt;
}
public static ItemProfile Create(Item item)
{
List<ItemProfile> contents = new List<ItemProfile>();
int primaryMagazine = 0;
int ammoType = 0;
if (item.contents != null)
{
if (item.contents.itemList.Count > 0)
{
foreach (Item content in item.contents.itemList)
{
contents.Add(Create(content));
}
}
}
var weapon = item.GetHeldEntity() as BaseProjectile;
if (weapon != null)
{
BaseProjectile projectile = weapon as BaseProjectile;
primaryMagazine = projectile.primaryMagazine.contents;
ammoType = projectile.primaryMagazine.ammoType.itemid;
}
int dataInt = 0;
if (item.instanceData != null && item.info.shortname == "door.key")
{
dataInt = item.instanceData.dataInt;
}
ItemProfile newItem = new ItemProfile(item.info.itemid.ToString(), item.amount, item.position, item.contents?.capacity ?? -1, item.flags, item.condition, item.skin, contents, primaryMagazine, ammoType, dataInt);
return newItem;
}
}
public class BankProfile
{
protected ulong playerID;
public List<ItemProfile> items = new List<ItemProfile>();
[JsonIgnore]
public bool open = false;
[JsonIgnore]
public bool dirty = false;
[JsonIgnore]
public BasePlayer Player
{
get
{
return BasePlayer.Find(playerID.ToString());
}
protected set
{
playerID = value.userID;
}
}
[JsonIgnore]
public ulong PlayerID
{
get { return playerID; }
private set { }
}
[JsonIgnore]
public int Count
{
get
{
return items.Count;
}
private set { }
}
public BankProfile()
{
}
public BankProfile(BasePlayer player, List<ItemProfile> items = null)
{
playerID = player.userID;
if (items is List<ItemProfile>)
{
this.items = items;
}
}
[JsonConstructor]
public BankProfile(ulong playerID, List<ItemProfile> items)
{
this.playerID = playerID;
this.items = items;
}
public bool Add(Item item)
{
ItemProfile profile = ItemProfile.Create(item);
items.Add(profile);
dirty = true;
return true;
}
public bool Add(Item[] items)
{
foreach (Item item in items)
{
if (!Add(item))
{
return false;
}
}
return true;
}
public bool Add(List<Item> items)
{
return Add(items.ToArray());
}
public bool Remove(Item item)
{
ItemProfile removing = null;
foreach (ItemProfile profile in this.items)
{
if (profile.id == item.info.itemid.ToString() && profile.amount == item.amount)
{
removing = profile;
break;
}
}
if (removing is ItemProfile)
{
dirty = true;
items.Remove(removing);
return true;
}
return false;
}
public bool Remove(Item[] items)
{
foreach (Item item in items)
{
if (!Remove(item))
{
return false;
}
}
return true;
}
public bool Remove(List<Item> items)
{
return Remove(items.ToArray());
}
[JsonIgnore]
ItemContainer container;
public ItemContainer SetContainer(ItemContainer container, BasePlayer player, int slots = 30)
{
if (this.container is ItemContainer)
{
this.container.playerOwner = player;
this.container.itemList.Clear();
PopulateContainer(player, this.container);
return this.container;
}
container.playerOwner = player;
PopulateContainer(player, container);
return this.container = container;
}
void PopulateContainer(BasePlayer player, ItemContainer container, List<ItemProfile> items = null)
{
if (items == null)
{
items = this.items;
}
foreach (ItemProfile profile in items)
{
Item item = ItemManager.CreateByItemID(Convert.ToInt32(profile.id), profile.amount);
var numberOfSlots = Math.Max(profile.capacity, profile.contents?.Count ?? -1);
if (item.contents == null && numberOfSlots > 0)
{
foreach (var itemmod in item.info.itemMods)
{
if (itemmod is ItemModContainerArmorSlot imcas)
{
imcas.CreateAtCapacity(numberOfSlots, item);
}
}
}
if (item is Item)
{
item.flags = profile.flags;
item.skin = profile.skin;
if (item.hasCondition)
{
item.condition = profile.condition;
}
var held = item.GetHeldEntity();
if (held is BaseEntity)
{
held.skinID = profile.skin;
}
var weapon = held as BaseProjectile;
if (weapon != null)
{
BaseProjectile projectile = weapon as BaseProjectile;
projectile.primaryMagazine.contents = profile.primaryMagazine;
if (profile.ammoType != 0)
{
projectile.primaryMagazine.ammoType = ItemManager.FindItemDefinition(profile.ammoType);
}
}
if (profile.contents != null)
{
if (profile.contents.Count > 0)
{
PopulateContainer(player, item.contents, profile.contents);
}
}
if (item.info.shortname == "door.key" && profile.dataInt != 0)
{
ProtoBuf.Item.InstanceData instanceData = Facepunch.Pool.Get<ProtoBuf.Item.InstanceData>();
item.instanceData = instanceData;
item.instanceData.ShouldPool = false;
item.instanceData.dataInt = profile.dataInt;
}
if (container != null) item.MoveToContainer(container, profile.slot);
}
}
}
}
#endregion
#region Configuration
class ItemLimit
{
public bool enabled;
public int minimum;
public int maximum;
[JsonConstructor]
public ItemLimit(bool enabled, int minimum, int maximum)
{
this.enabled = enabled;
this.minimum = minimum;
this.maximum = maximum;
}
}
#endregion
#region State
class OnlinePlayer
{
public BasePlayer Player;
public BasePlayer Target;
public StorageContainer View;
public List<BasePlayer> Matches;
public OnlinePlayer(BasePlayer player)
{
Player = player;
Target = null;
View = null;
Matches = new List<BasePlayer>();
}
}
public Dictionary<ItemContainer, ulong> containers = new Dictionary<ItemContainer, ulong>();
public Dictionary<ulong, BankProfile> banks = new Dictionary<ulong, BankProfile>();
// [OnlinePlayers]
Hash<BasePlayer, OnlinePlayer> onlinePlayers = new Hash<BasePlayer, OnlinePlayer>();
Dictionary<string, DateTime> bankCooldowns = new Dictionary<string, DateTime>();
#endregion
#region Initialization & Data
void Init()
{
Unsubscribe(nameof(OnEntityTakeDamage));
configFile = new DataFileSystem(Interface.Oxide.ConfigDirectory);
itemLimits = configFile.ReadObject<Dictionary<string, object>>("Bank_ItemLimits");
permission.RegisterPermission("bank.use", this);
CheckConfig();
datafile = new DataFileSystem(Interface.Oxide.DataDirectory + "\\" + this.GetConfig<string>("subDirectory", "banks"));
boxPrefabs = GetConfig("Settings", "boxes", GetDefaultBoxes());
boxSlots = GetConfig("Settings", "slots", GetDefaultSlots());
defaultBoxPrefab = GetConfig("Settings", "defaultBox", "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab");
defaultSlots = GetConfig("Settings", "defaultSlots", 4);
cooldownMinutes = GetConfig("Settings", "cooldownMinutes", 5f);
radiationMax = GetConfig("Settings", "radiationMax", 1f);
allowSafeZone = GetConfig("Settings", "allowSafeZone", true);
npconly = GetConfig("Settings", "NPCBankersOnly", false);
List<object> lnpcids = GetConfig("Settings", "NPCIDs", new List<object>());
foreach (object id in lnpcids)
{
npcids.Add(id.ToString());
}
keyring = GetConfig("Settings", "Keyring", true);
foreach (KeyValuePair<string, object> kvp in boxPrefabs)
{
permission.RegisterPermission(kvp.Key, this);
}
foreach (KeyValuePair<string, object> kvp in boxSlots)
{
if (!boxPrefabs.ContainsKey(kvp.Key))
{
permission.RegisterPermission(kvp.Key, this);
}
}
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
LoadProfile(player.userID);
EnsureOnline(player); // ensure OnlinePlayer entries exist for already-connected players
}
}
new void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
{"Denied: Permission", "You lack permission to do that"},
{"Denied: Privilege", "You lack build privileges and cannot do that"},
{"Denied: Swimming", "You cannot do that while swimming"},
{"Denied: Falling", "You cannot do that while falling"},
{"Denied: Wounded", "You cannot do that while wounded"},
{"Denied: Mounted", "You cannot do that while mounted"},
{"Denied: Generic", "You cannot do that right now"},
{"Denied: Irradiated", "You cannot do that while irradiated"},
{"Denied: Ship", "You cannot do that while on a ship"},
{"Denied: Lift", "You cannot do that while on a lift"},
{"Denied: Balloon", "You cannot do that while on a balloon"},
{"Denied: Safe Zone", "You cannot do that while in a safe zone"},
{"Cooldown: Seconds", "You are doing that too often, try again in a {0} seconds(s)."},
{"Cooldown: Minutes", "You are doing that too often, try again in a {0} minute(s)."},
{"Limit: Return", "Some items were returned to your inventory"}
}, this);
}
Dictionary<string, object> GetDefaultBoxes()
{
return new Dictionary<string, object>() {
{"bank.default", "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab"},
{"bank.big", "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab"}
};
}
Dictionary<string, object> GetDefaultSlots()
{
return new Dictionary<string, object>() {
{"bank.default", 4},
{"bank.big", 30}
};
}
Dictionary<string, object> GetDefaultItemLimits()
{
return new Dictionary<string, object>() {
{"explosive.timed", new ItemLimit(false, 0, 1)}
};
}
protected override void LoadDefaultConfig()
{
Config["Settings", "boxes"] = GetDefaultBoxes();
Config["Settings", "slots"] = GetDefaultSlots();
Config["Settings", "defaultBox"] = "assets/prefabs/deployable/woodenbox/woodbox_deployed.prefab";
Config["Settings", "defaultSlots"] = 4;
Config["Settings", "keyring"] = true;
Config["Settings", "cooldownMinutes"] = 5;
Config["Settings", "radiationMax"] = 1;
Config["Settings", "NPCBankersOnly"] = false;
Config["Settings", "NPCIDs"] = new List<object>();
Config["Settings", "allowSafeZone"] = true;
if (configFile == null)
configFile = new DataFileSystem(Interface.Oxide.ConfigDirectory);
configFile.WriteObject("Bank_ItemLimits", GetDefaultItemLimits());
Config["VERSION"] = Version.ToString();
}
void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
{
var ply = EnsureOnline(player);
if (ply != null && ply.View != null)
{
SaveProfileByUser(player.userID);
CloseBank(player, ply.View);
}
}
}
void OnServerSave()
{
SaveData();
}
void CheckConfig()
{
if (Config["VERSION"] == null)
{
// FOR COMPATIBILITY WITH INITIAL VERSIONS WITHOUT VERSIONED CONFIG
ReloadConfig();
}
else if (GetConfig<string>("VERSION", "") != Version.ToString())
{
// ADDS NEW, IF ANY, CONFIGURATION OPTIONS
ReloadConfig();
}
}
protected void ReloadConfig()
{
Config["VERSION"] = Version.ToString();
// NEW CONFIGURATION OPTIONS HERE
Config["Settings", "radiationMax"] = GetConfig("Settings", "radiationMax", 1f);
Config["Settings", "NPCBankersOnly"] = GetConfig("Settings", "NPCBankersOnly", false);
Config["Settings", "NPCIDs"] = GetConfig("Settings", "NPCIDs", new List<object>());
if (itemLimits.Count == 0)
{
itemLimits = GetDefaultItemLimits();
}
configFile.WriteObject("Bank_ItemLimits", itemLimits);
// END NEW CONFIGURATION OPTIONS
PrintWarning("Upgrading configuration file");
SaveConfig();
}
void SaveProfileByUser(ulong userID)
{
if (banks.ContainsKey(userID))
{
SaveProfile(userID, banks[userID]);
}
}
void SaveData()
{
int t = 0;
foreach (KeyValuePair<ulong, BankProfile> kvp in banks)
{
if (kvp.Value.dirty)
{
SaveProfile(kvp.Key, kvp.Value);
t++;
}
}
PrintToConsole("Saved " + t.ToString() + " banks");
}
protected bool LoadProfile(ulong playerID, bool reload = false)
{
#if DEBUG
Puts($"Loading Bank {playerID}");
#endif
if (playerID == 0)
{
return false;
}
string path = "bank_" + playerID.ToString();
BankProfile profile = datafile.ReadObject<BankProfile>(path);
if (!(profile is BankProfile))
{
return false;
}
if (profile.Count == 0)
{
return false;
}
if (banks.ContainsKey(playerID))
{
banks[playerID] = profile;
}
else
{
banks.Add(playerID, profile);
}
return true;
}
void SaveProfile(ulong playerID, BankProfile profile = null)
{
if (profile == null)
{
if (!banks.ContainsKey(playerID))
{
return;
}
profile = banks[playerID];
}
string path = "bank_" + playerID.ToString();
int pc = profile.Count;
datafile.WriteObject(path, profile);
profile.dirty = false;
}
#endregion
#region API
bool IsBankBox(BaseNetworkable entity)
{
foreach (KeyValuePair<BasePlayer, OnlinePlayer> kvp in onlinePlayers)
{
if (kvp.Value?.View?.net != null && entity?.net != null && kvp.Value.View.net.ID == entity.net.ID)
{
return true;
}
}
return false;
}
bool TryGetPlayer(BaseNetworkable entity, out BasePlayer player)
{
player = null;
foreach (KeyValuePair<BasePlayer, OnlinePlayer> kvp in onlinePlayers)
{
if (kvp.Value?.View?.net != null && entity?.net != null && kvp.Value.View.net.ID == entity.net.ID)
{
player = kvp.Value.Player;
return true;
}
}
return false;
}
void AddNpc(string id)
{
npcids.Add(id);
}
void AddNpc(ulong id)
{
AddNpc(id.ToString());
}
void RemoveNpc(string id)
{
if (npcids.Contains(id))
{
npcids.Remove(id);
}
}
void RemoveNpc(ulong id)
{
RemoveNpc(id.ToString());
}
#endregion
#region Oxide Hooks
void OnUseNPC(BasePlayer npc, BasePlayer player)
{
if (!npcids.Contains(npc.UserIDString)) return;
ShowBank(player, player);
}
object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
{
if (hitInfo == null)
return null;
if (entity == null)
return null;
if (IsBankBox(entity))
return false;
return null;
}
object CanUseLockedEntity(BasePlayer player, BaseLock lockItem)
{
if (player == null) return null;
if (lockItem == null) return null;
if (!keyring) return null;
if (MasterKey != null)
{
var result = MasterKey.Call("CanUseLockedEntity", player, lockItem);
if (result is bool)
{
return null;
}
}
BankProfile bank;
if (lockItem is KeyLock && banks.TryGetValue(player.userID, out bank) && bank.items != null)
{
KeyLock keyLock = (KeyLock)lockItem;
List<int> codes = bank.items.Select(profile => profile.dataInt).Where(dataInt => dataInt != 0).ToList();
if (!keyLock.IsLocked())
{
return null;
}
if (keyLock.HasLockPermission(player))
{
return null;
}
foreach (int code in codes)
{
if (code == keyLock.keyCode)
{
return true;
}
}
return false;
}
return null;
}
void OnPlayerConnected(BasePlayer player)
{
var ply = EnsureOnline(player);
if (ply != null)
{
ply.View = null;
ply.Target = null;
ply.Matches = new List<BasePlayer>();
}
if (!LoadProfile(player.userID))
{
if (!banks.ContainsKey(player.userID))
{
banks.Add(player.userID, new BankProfile(player));
}
}
}
void OnPlayerDisconnected(BasePlayer player)
{
var ply = EnsureOnline(player);
if (ply != null && ply.View != null)
{
CloseBank(player, ply.View);
SaveProfile(player.userID);
}
}
void OnPlayerLootEnd(PlayerLoot inventory)
{
BasePlayer player;
if ((player = inventory.GetComponent<BasePlayer>()) == null)
return;
var ply = EnsureOnline(player);
if (ply != null && ply.View != null && ply.View == inventory.entitySource)
{
CloseBank(player, (StorageContainer)inventory.entitySource);
}
}
// (Optional) Guarded implementation exists for item limits if you later re-enable it
//void OnItemAddedToContainer(ItemContainer container, Item item) { ... }
#endregion
#region Commands
[ChatCommand("viewbank")]
void ViewBank(BasePlayer player, string command, string[] args)
{
if (!IsAllowed(player)) return;
if (args.Length < 1)
{
return;
}
var name = args[0];
var ply = EnsureOnline(player);
if (ply == null) return;
if (name == "list")
{
if (ply.Matches == null)
{
return;
}
if (args.Length == 1)
{
ShowMatchingPlayers(player);
return;
}
int index;
if (!int.TryParse(args[1], out index))
{
return;
}
if (index > ply.Matches.Count) { }
else
ShowBank(player, ply.Matches[index - 1]);
return;
}
var matches = FindPlayersByName(name);
if (matches.Count < 1)
{
return;
}
if (matches.Count > 1)
{
ply.Matches = matches;
ShowMatchingPlayers(player);
return;
}
ShowBank(player, matches[0]);
}
[ConsoleCommand("bank")]
void ccBank(ConsoleSystem.Arg arg)
{
cmdBank(arg.Connection.player as BasePlayer, arg.cmd.Name, arg.Args);
}
[ChatCommand("bank")]
void cmdBank(BasePlayer player, string command, string[] args)
{
if (npconly) return;
ShowBank(player, player);
}
#endregion
#region Core methods
ItemLimit GetItemLimit(Item item)
{
object limit;
if (itemLimits.TryGetValue(item.info.shortname, out limit) && limit is JObject)
{
return ((JObject)limit).ToObject<ItemLimit>();
}
return null;
}
bool CanPlayerBank(BasePlayer player)
{
if (player.IsAdmin)
{
return true;
}
if (!permission.UserHasPermission(player.UserIDString, "bank.use"))
{
SendReply(player, GetMsg("Denied: Permission", player));
return false;
}
if (!player.CanBuild() && !npconly)
{
SendReply(player, GetMsg("Denied: Privilege", player));
return false;
}
if (radiationMax > 0 && player.radiationLevel > radiationMax)
{
SendReply(player, GetMsg("Denied: Irradiated", player));
return false;
}
if (player.IsSwimming())
{
SendReply(player, GetMsg("Denied: Swimming", player));
return false;
}
if (!player.IsOnGround() || player.IsFlying || player.isInAir)
{
SendReply(player, GetMsg("Denied: Falling", player));
return false;
}
if (player.isMounted)
{
SendReply(player, GetMsg("Denied: Mounted", player));
return false;
}
if (player.IsWounded())
{
SendReply(player, GetMsg("Denied: Wounded", player));
return false;
}
if (player.GetComponentInParent<CargoShip>())
{
SendReply(player, GetMsg("Denied: Ship", player));
return false;
}
if (player.GetComponentInParent<HotAirBalloon>())
{
SendReply(player, GetMsg("Denied: Balloon", player));
return false;
}
if (player.GetComponentInParent<Lift>())
{
SendReply(player, GetMsg("Denied: Lift", player));
return false;
}
if (!allowSafeZone && player.InSafeZone())
{
SendReply(player, GetMsg("Denied: Safe Zone", player));
return false;
}
var canBank = Interface.Call("CanBank", player);
if (canBank != null)
{
if (canBank is string)
{
SendReply(player, Convert.ToString(canBank));
}
else
{
SendReply(player, GetMsg("Denied: Generic", player));
}
return false;
}
return true;
}
void ShowBank(BasePlayer player, BaseEntity target)
{
if (!CanPlayerBank(player))
return;
string playerID = player.userID.ToString();
var authLevel = player?.net?.connection?.authLevel ?? 0;
if (cooldownMinutes > 0 && authLevel < 1)
{
if (bankCooldowns.ContainsKey(playerID))
{
DateTime startTime = bankCooldowns[playerID];
DateTime endTime = DateTime.Now;
TimeSpan span = endTime.Subtract(startTime);
if (span.TotalMinutes > 0 && span.TotalMinutes < Convert.ToDouble(cooldownMinutes))
{
double timeleft = System.Math.Round(Convert.ToDouble(cooldownMinutes) - span.TotalMinutes, 2);
if (timeleft < 1)
{
double timelefts = System.Math.Round((Convert.ToDouble(cooldownMinutes) * 60) - span.TotalSeconds);
SendReply(player, string.Format(GetMsg("Cooldown: Seconds", player), timelefts.ToString()));
}
else
{
SendReply(player, string.Format(GetMsg("Cooldown: Minutes", player), System.Math.Round(timeleft).ToString()));
}
return;
}
else
{
bankCooldowns.Remove(playerID);
}
}
}
if (!LoadProfile(player.userID) && !banks.ContainsKey(player.userID))
{
banks.Add(player.userID, new BankProfile(player));
}
if (!bankCooldowns.ContainsKey(player.userID.ToString()) && authLevel < 1)
{
bankCooldowns.Add(playerID, DateTime.Now);
}
var ply = EnsureOnline(player);
if (ply == null) return;
if (ply.View == null)
{
#if DEBUG
Puts($"Opening bank {player.userID}");
#endif
OpenBank(player, target);
return;
}
// Player must close (Esc) before opening again – avoids spam/bind abuse.
// CloseBank(player, ply.View);
// timer.In(1f, () => OpenBank(player, target));
}
void HideBank(BasePlayer player)
{
player.EndLooting();
var ply = EnsureOnline(player);
if (ply == null || ply.View == null)
{
return;
}
CloseBank(player, ply.View);
}
string GetBox(BasePlayer player)
{
foreach (KeyValuePair<string, object> kvp in boxPrefabs)
{
if (permission.UserHasPermission(player.UserIDString, kvp.Key))
{
return kvp.Value.ToString();
}
}
return defaultBoxPrefab;
}
int GetSlots(BasePlayer player)
{
var availableSlots = new List<int>();
availableSlots.Add(defaultSlots);
foreach (KeyValuePair<string, object> kvp in boxSlots)
{
if (permission.UserHasPermission(player.UserIDString, kvp.Key))
{
availableSlots.Add(Convert.ToInt32(kvp.Value));
}
}
return availableSlots.Max();
}
void OpenBank(BasePlayer player, BaseEntity targArg)
{
Subscribe(nameof(OnEntityTakeDamage));
var pos = new Vector3(player.transform.position.x, player.transform.position.y - 1, player.transform.position.z);
string box = GetBox(player);
int slots = GetSlots(player);
var view = GameManager.server.CreateEntity(box, pos) as StorageContainer;
view.SetFlag(BaseEntity.Flags.Disabled, true);
var groundWatch = view.GetComponent<GroundWatch>();
if (groundWatch != null)
{
UnityEngine.Object.Destroy(groundWatch);
groundWatch.fails = int.MinValue;
}
UnityEngine.Object.Destroy(view.GetComponent<DestroyOnGroundMissing>());
foreach (Collider collider in view.GetComponentsInChildren<Collider>())
{
UnityEngine.Object.DestroyImmediate(collider);
}
view.limitNetworking = true;
view.SetParent(player, true, true);
if (!view) return;
view.transform.position = pos;
view.OwnerID = player.userID;
player.EndLooting();
if (targArg is BasePlayer)
{
BasePlayer target = targArg as BasePlayer;
BankProfile profile = banks[target.userID];
view.inventorySlots = slots;
// use CreateInventory instead of _inventory directly because
// CreateInventory and DoServerDestroy use the Pool function for alloc and free
view.CreateInventory(true);
ItemContainer bank = profile.SetContainer(view.inventory, target, slots);
if (!containers.ContainsKey(bank))
{
containers.Add(bank, player.userID);
}
view.enableSaving = false;
view.Spawn();
view.inventory.entityOwner = view;
profile.open = true;
var ply = EnsureOnline(player);
if (ply != null)
{
ply.View = view;
ply.Target = target;
}
timer.In(0.1f, delegate ()
{
view.PlayerOpenLoot(player);
});
}
}
void CloseBank(BasePlayer player, StorageContainer view)
{
var ply = EnsureOnline(player);
if (ply == null) return;
if (ply.View == null) return;
if (!banks.ContainsKey(player.userID))
{
return;
}
BankProfile profile = banks[player.userID];
InvalidateBank(player, profile, view);
profile.items.Clear();
foreach (Item item in view.inventory.itemList)
{
profile.Add(item);
}
SaveProfile(player.userID, profile);
foreach (Item item in view.inventory.itemList.ToArray())
{
if (item.position != -1)
{
item.RemoveFromContainer();
item.Remove(0f);
}
}
profile.open = false;
if (containers.ContainsKey(view.inventory))
{
containers.Remove(view.inventory);
}
player.inventory.loot.containers = new List<ItemContainer>();
if (player.inventory.loot.IsLooting())
{
player.SendConsoleCommand("inventory.endloot", null);
}
ply.View = null;
ply.Target = null;
view.Kill(BaseNetworkable.DestroyMode.None);
#if DEBUG
Puts($"Closing Bank {player.userID}, view: {onlinePlayers.Values.Count(p => p.View != null)}");
#endif
timer.In(1f, delegate ()
{
if (onlinePlayers.Values.Count(p => p.View != null) <= 0)
{
Unsubscribe(nameof(OnEntityTakeDamage));
}
});
}
void InvalidateBank(BasePlayer player, BankProfile profile, StorageContainer view)
{
bool returned = false;
if (view != null && view.inventory != null && view.inventory.itemList != null)
{
foreach (var item in view.inventory.itemList.ToArray())
{
ItemLimit limit = GetItemLimit(item);
if (limit != null && limit.enabled)
{
if (item.amount < limit.minimum)
{
returned = true;
if (player.inventory.containerMain == null || (player.inventory.containerMain != null && !item.MoveToContainer(player.inventory.containerMain)))
{
if (player.inventory.containerBelt == null || (player.inventory.containerBelt != null && !item.MoveToContainer(player.inventory.containerBelt)))
{
item.Drop(player.eyes.HeadForward() * 2, default(Vector3));
}
}
continue;
}
if (item.amount > limit.maximum)
{
returned = true;
Item invalidItem;
if (limit.maximum > 0)
{
invalidItem = item.SplitItem(item.amount - limit.maximum);
}
else
{
invalidItem = item;
}
if (invalidItem != null)
{
if (player.inventory.containerMain == null || (player.inventory.containerMain != null && !invalidItem.MoveToContainer(player.inventory.containerMain)))
{
if (player.inventory.containerBelt == null || (player.inventory.containerBelt != null && !invalidItem.MoveToContainer(player.inventory.containerBelt)))
{
invalidItem.Drop(player.eyes.HeadForward() * 2, default(Vector3));
}
}
}
}
}
}
}
if (returned)
{
SendReply(player, GetMsg("Limit: Return", player));
}
}
#endregion
#region HelpText
void SendHelpText(BasePlayer player)
{
var sb = new StringBuilder()
.Append("Bank by <color=#ce422b>Calytic</color>\n")
.Append(" ").Append("<color=\"#ffd479\">/bank</color> - Open your bank box").Append("\n");
if (player.IsAdmin)
{
sb.Append(" ").Append("<color=\"#ffd479\">/viewbank \"Player Name\"</color> - View any players bank").Append("\n");
}
player.ChatMessage(sb.ToString());
}
#endregion
#region Helper methods
string GetMsg(string key, BasePlayer player = null)
{
return lang.GetMessage(key, this, player == null ? null : player.UserIDString);
}
List<BasePlayer> FindPlayersByName(string name)
{
List<BasePlayer> matches = new List<BasePlayer>();
foreach (var ply in BasePlayer.activePlayerList)
{
if (ply.displayName.ToLower().Contains(name.ToLower()))
matches.Add(ply);
}
foreach (var ply in BasePlayer.sleepingPlayerList)
{
if (ply.displayName.ToLower().Contains(name.ToLower()))
matches.Add(ply);
}
return matches;
}
void ShowMatchingPlayers(BasePlayer player)
{
var ply = EnsureOnline(player);
if (ply == null || ply.Matches == null) return;
int i = 0;
foreach (var mp in ply.Matches)
{
i++;
player.ChatMessage($"{i} - {mp.displayName} ({mp.userID})");
}
}
bool IsAllowed(BasePlayer player)
{
if (player.IsAdmin) return true;
SendReply(player, GetMsg("Denied: Permission", player));
return false;
}
T GetConfig<T>(string name, string name2, T defaultValue)
{
if (Config[name, name2] == null)
{
return defaultValue;
}
return (T)Convert.ChangeType(Config[name, name2], typeof(T));
}
T GetConfig<T>(string name, T defaultValue)
{
if (Config[name] == null)
{
return defaultValue;
}
return (T)Convert.ChangeType(Config[name], typeof(T));
}
OnlinePlayer EnsureOnline(BasePlayer player)
{
if (player == null) return null;
OnlinePlayer op;
if (!onlinePlayers.TryGetValue(player, out op) || op == null)
{
op = new OnlinePlayer(player);
onlinePlayers[player] = op;
}
// keep pointer fresh
op.Player = player;
return op;
}
#endregion
}
}
This is because Carbon is not 100% compatible with Oxide