C#:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
// Requires: Backpacks
using Oxide.Game.Rust.Cui;
using Network;
namespace Oxide.Plugins
{
[Info("BPUpgrader", "David", "2.0.0")]
public class BPUpgrader : RustPlugin
{
[PluginReference]
private Plugin Economics, ServerRewards, Notifications, ImageLibrary;
#region cmds/hooks/functions
List<string> upgrades = new List<string>();
void OnServerInitialized()
{
LoadData();
if (ImageLibrary != null)
ImageLibrary.Call("AddImage", "https://rustplugins.net/products/bp_orig.png", "https://rustplugins.net/products/bp_orig.png");
// if upgrades are empty
if (config.upgrades.Count == 0)
{
Puts("No upgrades found in config, populating based on what is available in Backpacks plugin...");
var perms = permission.GetPermissions();
foreach (var perm in perms)
{
if (config.useRows)
{
//skip first level
if (perm == "backpacks.use.1") continue;
if (perm.Contains("backpacks.use."))
config.upgrades.Add(perm, Convert.ToInt32(perm.Split('.')[2]) * 10);
}
else
{
if (perm.Contains("backpacks.size."))
config.upgrades.Add(perm, Convert.ToInt32(perm.Split('.')[2]) * 10);
}
}
SaveConfig();
}
foreach (string perm in config.upgrades.Keys)
upgrades.Add(perm);
}
void OnPlayerConnected(BasePlayer player)
{
if (config.wipe && playerData.Contains(player.UserIDString))
{
foreach (string perm in upgrades)
{
if (permission.UserHasPermission(player.UserIDString, perm))
permission.RevokeUserPermission(player.UserIDString, perm);
}
}
}
void OnServerSave() => SaveData();
void OnNewSave()
{
LoadData();
playerData.Clear();
SaveData();
}
int GetCurrentLevel(BasePlayer player)
{
for (int i = upgrades.Count; i > 0; i--)
{
if (permission.UserHasPermission(player.UserIDString, upgrades[i - 1]))
return i;
}
return 0;
}
private bool TakeFrom(BasePlayer player, string currencyType, int amount)
{
if (currencyType.ToLower() != "rp" && currencyType.ToLower() != "eco")
{
var itemDef = ItemManager.FindItemDefinition(currencyType);
if (itemDef == null)
{ Puts($" <color=#C2291D>!</color> '{currencyType}' <color=#C2291D>is not correct shortname.</color>"); return false; }
int inventory = player.inventory.GetAmount(itemDef.itemid);
if (inventory < amount)
{
return false;
}
player.inventory.Take(null, itemDef.itemid, amount);
return true;
}
if (currencyType == "rp")
{
if (ServerRewards == null)
{ Puts("ServerRewards is not loaded!"); return false; }
var playersRP = ServerRewards?.Call<int>("CheckPoints", player.userID);
if (playersRP < amount) return false;
ServerRewards?.Call("TakePoints", player.userID, amount);
return true;
}
if (currencyType == "eco")
{
if (Economics == null)
{ Puts("Economics is not loaded!"); return false; }
double playersEco = Economics.Call<double>("Balance", player.UserIDString);
if (playersEco < Convert.ToDouble(amount))
{
return false;
}
Economics.CallHook("Withdraw", player.UserIDString, Convert.ToDouble(amount));
return true;
}
return false;
}
[ConsoleCommand("bpu_upgrade")]
private void bpu_upgrade(ConsoleSystem.Arg arg)
{
var player = arg?.Player();
var args = arg.Args;
if (player == null) return;
int lvl = GetCurrentLevel(player);
switch(args[0])
{
case "upgrade":
if (lvl >= upgrades.Count)
{
if (Notifications != null)
{
Notifications.Call("Run",
player,
3,
GL("fully_upgraded"),
"0.894 0.596 0.149 1.00",
(ImageLibrary != null ? ImageLibrary.Call("GetImage", "https://rustplugins.net/products/bp_orig.png") : "https://rustplugins.net/products/bp_orig.png"),
true
);
}
else
SendReply(player, GL("fully_upgraded"));
break;
}
ConfirmUpgradeUI(player);
break;
case "pay":
if (TakeFrom(player, config.currency, config.upgrades[upgrades[lvl]]))
{
permission.GrantUserPermission($"{player.userID}", $"{upgrades[lvl]}", null);
if (Notifications != null)
{
Notifications.Call("Run",
player,
3,
GL("on_upgrade").Replace("{level}", $"{lvl}"),
"0.376 0.753 0.247 1.00",
(ImageLibrary != null ? ImageLibrary.Call("GetImage", "https://rustplugins.net/products/bp_orig.png") : "https://rustplugins.net/products/bp_orig.png"),
true
);
}
else
SendReply(player, GL("on_upgrade"));
PlayFx(player, config.upgradefx);
player.ClientRPCPlayer(null, player, "OnRespawnInformation");
NextTick(() => {
player.SendConsoleCommand($"chat.say /backpack");
});
break;
}
else
{
if (Notifications != null)
{
Notifications.Call("Run",
player,
3,
GL("insufficient_funds"),
"0.757 0.259 0.161 1.00",
(ImageLibrary != null ? ImageLibrary.Call("GetImage", "https://rustplugins.net/products/bp_orig.png") : "https://rustplugins.net/products/bp_orig.png"),
true
);
}
else
SendReply(player, GL("insufficient_funds"));
break;
}
case "close":
CuiHelper.DestroyUi(player, "bpu_upgradebtn_confirm");
break;
default:
//
break;
}
}
void OnBackpackClosed(BasePlayer player) => CuiHelper.DestroyUi(player, "bpu_upgradebtn");
void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
CuiHelper.DestroyUi(player, "bpu_upgradebtn");
SaveData();
}
private void PlayFx(BasePlayer player, string fx)
{
if (player == null) return;
var EffectInstance = new Effect();
EffectInstance.Init(Effect.Type.Generic, player, 0, Vector3.up, Vector3.zero);
EffectInstance.pooledstringid = StringPool.Get(fx);
NetWrite netWrite = Net.sv.StartWrite();
netWrite.PacketID(Message.Type.Effect);
EffectInstance.WriteToStream(netWrite);
netWrite.Send(new SendInfo(player.net.connection));
EffectInstance.Clear();
}
#endregion
#region ui
string[] offsets = {
"240 203-290 223",
"240 266-290 286",
"240 328-290 348",
"240 390-290 410",
"240 452-290 472",
"240 514-290 534",
"240 577-290 597",
"0 0-0 0",
};
void OnBackpackOpened(BasePlayer player, ulong backpackOwnerID, ItemContainer backpackContainer)
{
string[] offset = offsets[(int)Math.Ceiling((float)backpackContainer.capacity / 6) - 1].Split('-');
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0.5 0.0", AnchorMax = "0.5 0.0", OffsetMin = offset[0], OffsetMax = offset[1]},
Button = { Color = $"0.31 0.37 0.20 1.0", Sprite = "", Command = "bpu_upgrade upgrade"},
Text = { FadeIn = 0.2f, Text = $"UPGRADE", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 10, Color = "1 1 1 0.7"}
}, "Overlay", "bpu_upgradebtn");
CuiHelper.DestroyUi(player, "bpu_upgradebtn");
PlayFx(player, config.soundfx);
NextTick(() =>{
CuiHelper.AddUi(player, container);
});
}
void ConfirmUpgradeUI(BasePlayer player)
{
int lvl = GetCurrentLevel(player);
string _price = $"{config.upgrades[upgrades[lvl]]}";
if (config.currency.ToLower() != "rp" && config.currency.ToLower() != "eco")
_price += $"<size=7>{config.currency.ToUpper()}</size>";
if (config.currency.ToLower() == "rp")
_price += $" RP";
if (config.currency.ToLower() == "eco")
_price += $" $";
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1.0 1"},
Button = { Color = "0.31 0.37 0.20 1.0", Sprite = "", Command = "bpu_upgrade pay"},
Text = { FadeIn = 0.2f, Text = _price, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 10, Color = "1 1 1 0.7"}
}, "bpu_upgradebtn", "bpu_upgradebtn_confirm");
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "1.05 0.05", AnchorMax = "1.4 0.95"},
Button = { Color = "0.56 0.20 0.15 1.0", Sprite = "", Command = "bpu_upgrade close"},
Text = { FadeIn = 0.2f, Text = $"✘", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 10, Color = "1 1 1 0.7"}
}, "bpu_upgradebtn_confirm", "bpu_upgradebtn_confirm_x");
CuiHelper.DestroyUi(player, "bpu_upgradebtn_confirm");
CuiHelper.AddUi(player, container);
}
#endregion
#region [Data]
private void SaveData()
{
if (playerData != null)
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/PlayerData", playerData);
}
private List<string> playerData;
private void LoadData()
{
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/PlayerData"))
{
playerData = Interface.Oxide.DataFileSystem.ReadObject<List<string>>($"{Name}/PlayerData");
}
else
{
playerData = new List<string>();
SaveData();
}
}
#endregion
#region config
private Configuration config;
protected override void LoadConfig()
{
base.LoadConfig();
config = Config.ReadObject<Configuration>();
SaveConfig();
}
protected override void LoadDefaultConfig() => config = Configuration.CreateConfig();
protected override void SaveConfig() => Config.WriteObject(config);
class Configuration
{
[JsonProperty("Reset upgrades on wipe.")]
public bool wipe {get; set;}
[JsonProperty("Using legacy backpack option (Rows)")]
public bool useRows {get; set;}
[JsonProperty("Currency type (shortname/eco/rp).")]
public string currency {get; set;}
[JsonProperty("Sound prefab when opening backpack (leave empty to disable).")]
public string soundfx {get; set;}
[JsonProperty("Sound prefab when upgrading backpack (leave empty to disable).")]
public string upgradefx {get; set;}
[JsonProperty("Upgrade permissions and prices.")]
public Dictionary<string, int> upgrades {get; set;}
public static Configuration CreateConfig()
{
return new Configuration
{
wipe = true,
useRows = false,
currency = "scrap",
soundfx = "assets/prefabs/deployable/locker/sound/equip_zipper.prefab",
upgradefx = "assets/prefabs/deployable/vendingmachine/effects/vending-machine-purchase-human.prefab",
upgrades = new Dictionary<string, int>{}
};
}
}
#endregion
#region Localization
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["fully_upgraded"] = "Your backpack is fully upgraded already.",
["insufficient_funds"] = "Insufficient funds!",
["on_upgrade"] = "Your backpack was succesfully upgraded to <b>level {level}!</b>",
}, this);
}
private string GL(string _message) => lang.GetMessage(_message, this);
#endregion
}
}