RustServer/plugins/SkinBox.cs

1933 lines
81 KiB
C#

using System;
using System.Text;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using UnityEngine;
using Steamworks;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins
{
[Info("SkinBox", "FuJiCuRa", "1.16.10", ResourceId = 17)]
[Description("SkinBox is a plugin to convert any skinnable item into each skin variant")]
internal class SkinBox : RustPlugin
{
[PluginReference] private Plugin QuickSort, ServerRewards, Economics, StacksExtended;
private bool skinsLoaded;
private bool Initialized;
private bool Changed;
private static SkinBox skinBox = null;
private bool activeServerRewards;
private bool activeEconomics;
private bool activeScrap;
private bool activePointSystem;
private int scrapItemId;
private int maxItemsShown;
private bool _stacksExtendedExtrasDisabled;
private Dictionary<string, LinkedList<ulong>> skinsCache = new Dictionary<string, LinkedList<ulong>>();
private Dictionary<string, LinkedList<ulong>> skinsCacheLimited = new Dictionary<string, LinkedList<ulong>>();
private Dictionary<string, int> approvedSkinsCount = new Dictionary<string, int>();
private Dictionary<string, DateTime> cooldownTimes = new Dictionary<string, DateTime>();
private Dictionary<string, string> NameToItemName = new Dictionary<string, string>();
private Dictionary<string, string> ItemNameToName = new Dictionary<string, string>();
private Dictionary<string, object> manualAddedSkinsPre = new Dictionary<string, object>();
private Dictionary<string, HashSet<ulong>> manualAddedSkins = new Dictionary<string, HashSet<ulong>>();
private List<ulong> excludedSkins = new List<ulong>();
private List<object> excludedSkinsPre = new List<object>();
private Dictionary<ulong, SBH> activeSkinBoxes = new Dictionary<ulong, SBH>();
private Dictionary<ulong, string> skinWorkshopNames = new Dictionary<ulong, string>();
private List<object> altSkinBoxCommand;
private string skinBoxCommand;
private string permissionUse;
private string permissionAdmin;
private bool showLoadedSkinCounts;
private int exludedSkinsAuthLevel;
private bool hideQuickSort;
private string steamApiKey;
private int accessOverrideAuthLevel;
private bool allowStackedItems;
private bool enableCustomPerms;
private string permCustomPlayerwearable;
private string permCustomWeapon;
private string permCustomDeployable;
private bool useInbuiltSkins;
private bool useApprovedSkins;
private int approvedSkinsLimit;
private bool useManualAddedSkins;
private int maxPagesShown;
private bool enableCooldown;
private int cooldownBox;
private bool cooldownOverrideAdmin;
private int cooldownOverrideAuthLevel;
private bool activateAfterSkinTaken;
private bool enableUsageCost;
private bool useServerRewards;
private bool useEconomics;
private bool useScrap;
private int costBoxOpen;
private int costWeapon;
private int costPlayerwearable;
private int costDeployable;
private bool costExcludeAdmins;
private string costExcludePerm;
private bool costExcludePermEnabled;
private object GetConfig(string menu, string datavalue, object defaultValue)
{
Dictionary<string, object> data = Config[menu] as Dictionary<string, object>;
if (data == null)
{
data = new Dictionary<string, object>();
Config[menu] = data;
Changed = true;
}
object value;
if (!data.TryGetValue(datavalue, out value))
{
value = defaultValue;
data[datavalue] = value;
Changed = true;
}
return value;
}
private object getSkincache()
{
if (skinsLoaded) return new Dictionary<string, LinkedList<ulong>>(skinsCache);
else return false;
}
private void LoadVariables()
{
useInbuiltSkins = Convert.ToBoolean(GetConfig("AvailableSkins", "useInbuiltSkins", true));
useApprovedSkins = Convert.ToBoolean(GetConfig("AvailableSkins", "useApprovedSkins", false));
approvedSkinsLimit = Convert.ToInt32(GetConfig("AvailableSkins", "approvedSkinsLimit", -1));
useManualAddedSkins = Convert.ToBoolean(GetConfig("AvailableSkins", "useManualAddedSkins", true));
maxPagesShown = Convert.ToInt32(GetConfig("AvailableSkins", "maxPagesShown", 2));
skinBoxCommand = Convert.ToString(GetConfig("Settings", "skinBoxCommand", "skinbox"));
altSkinBoxCommand = (List<object>)GetConfig("Settings", "altSkinBoxCommands", new List<object>());
permissionUse = Convert.ToString(GetConfig("Settings", "permissionUse", "skinbox.use"));
permissionAdmin = Convert.ToString(GetConfig("Settings", "permissionAdmin", "skinbox.admin"));
showLoadedSkinCounts = Convert.ToBoolean(GetConfig("Settings", "showLoadedSkinCounts", true));
exludedSkinsAuthLevel = Convert.ToInt32(GetConfig("Settings", "exludedSkinsAuthLevel", 2));
accessOverrideAuthLevel = Convert.ToInt32(GetConfig("Settings", "accessOverrideAuthLevel", 2));
hideQuickSort = Convert.ToBoolean(GetConfig("Settings", "hideQuickSort", true));
allowStackedItems = Convert.ToBoolean(GetConfig("Settings", "allowStackedItems", false));
steamApiKey = Convert.ToString(GetConfig("Settings", "steamApiKey", "https://steamcommunity.com/dev/apikey << get it THERE and saved it HERE"));
enableCustomPerms = Convert.ToBoolean(GetConfig("CustomPermissions", "enableCustomPerms", false));
permCustomPlayerwearable = Convert.ToString(GetConfig("CustomPermissions", "permCustomPlayerwearable", "skinbox.playerwearable"));
permCustomWeapon = Convert.ToString(GetConfig("CustomPermissions", "permCustomWeapon", "skinbox.weapon"));
permCustomDeployable = Convert.ToString(GetConfig("CustomPermissions", "permCustomDeployable", "skinbox.deployable"));
enableCooldown = Convert.ToBoolean(GetConfig("Cooldown", "enableCooldown", false));
cooldownBox = Convert.ToInt32(GetConfig("Cooldown", "cooldownBox", 60));
cooldownOverrideAdmin = Convert.ToBoolean(GetConfig("Cooldown", "cooldownOverrideAdmin", true));
cooldownOverrideAuthLevel = Convert.ToInt32(GetConfig("Cooldown", "cooldownOverrideAuthLevel", 2));
activateAfterSkinTaken = Convert.ToBoolean(GetConfig("Cooldown", "activateAfterSkinTaken", true));
manualAddedSkinsPre = (Dictionary<string, object>) GetConfig("SkinsAdded", "SkinList", new Dictionary<string, object> { });
excludedSkinsPre = (List<object>) GetConfig("SkinsExcluded", "SkinList", new List<object> { });
enableUsageCost = Convert.ToBoolean(GetConfig("UsageCost", "enableUsageCost", false));
useServerRewards = Convert.ToBoolean(GetConfig("UsageCost", "useServerRewards", true));
useEconomics = Convert.ToBoolean(GetConfig("UsageCost", "useEconomics", false));
useScrap = Convert.ToBoolean(GetConfig("UsageCost", "useScrap", false));
costBoxOpen = Convert.ToInt32(GetConfig("UsageCost", "costBoxOpen", 5));
costWeapon = Convert.ToInt32(GetConfig("UsageCost", "costWeapon", 30));
costPlayerwearable = Convert.ToInt32(GetConfig("UsageCost", "costPlayerwearable", 20));
costDeployable = Convert.ToInt32(GetConfig("UsageCost", "costDeployable", 10));
costExcludeAdmins = Convert.ToBoolean(GetConfig("UsageCost", "costExcludeAdmins", true));
costExcludePerm = Convert.ToString(GetConfig("UsageCost", "costExcludePerm", "skinbox.costexcluded"));
costExcludePermEnabled = Convert.ToBoolean(GetConfig("UsageCost", "costExcludePermEnabled", false));
bool configremoval = false;
if ((Config.Get("AvailableSkins") as Dictionary<string, object>).ContainsKey("useWebskinsRankedByTrend"))
{
(Config.Get("AvailableSkins") as Dictionary<string, object>).Remove("useWebskinsRankedByTrend");
(Config.Get("AvailableSkins") as Dictionary<string, object>).Remove("usedRankedByTrendDays");
(Config.Get("AvailableSkins") as Dictionary<string, object>).Remove("usedConnectionsToWorkshop");
configremoval = true;
}
if (!Changed & !configremoval)
return;
SaveConfig();
Changed = false;
configremoval = false;
}
protected override void LoadDefaultConfig()
{
Config.Clear();
LoadVariables();
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(
new Dictionary<string, string>
{
{"NoPermission", "You don't have permission to use the SkinBox"},
{"ToNearPlayer", "The SkinBox is currently not usable at this place"},
{"CooldownTime", "You need to wait {0} seconds to re-open the SkinBox again"},
{"NotEnoughBalanceOpenRP", "You need at least '{0}' RP to open the SkinBox"},
{"NotEnoughBalanceOpenEco", "You need at least '{0}' bucks to open the SkinBox"},
{"NotEnoughBalanceOpenScrap", "You need at least '{0}' scrap to open the SkinBox"},
{"NotEnoughBalanceUseRP", "You would need at least '{0}' RP to skin '{1}'"},
{"NotEnoughBalanceUseEco", "You would need at least '{0}' bucks to skin '{1}'"},
{"NotEnoughBalanceUseScrap", "You would need at least '{0}' scrap to skin '{1}'"},
{"NotEnoughBalanceTakeRP", "'{0}' was not skinned. You do not have enough RP"},
{"NotEnoughBalanceTakeEco", "'{0}' was not skinned. You do not have enough bucks"},
{"NotEnoughBalanceTakeScrap", "'{0}' was not skinned. You do not have enough scrap"},
}, this);
}
private void Loaded()
{
LoadVariables();
LoadDefaultMessages();
if (allowStackedItems) SbscrbSplt();
else UnsbscrbSplt();
cmd.AddChatCommand(skinBoxCommand, this, "cmdSknBx");
for (int i = 0; i < altSkinBoxCommand.Count; i++)
cmd.AddChatCommand(altSkinBoxCommand[i].ToString(), this, "cmdSknBx");
permission.RegisterPermission(permissionAdmin, this);
permission.RegisterPermission(permissionUse, this);
permission.RegisterPermission(permCustomPlayerwearable, this);
permission.RegisterPermission(permCustomWeapon, this);
permission.RegisterPermission(permCustomDeployable, this);
permission.RegisterPermission(costExcludePerm, this);
skinsCache = new Dictionary<string, LinkedList<ulong>>();
skinsCacheLimited = new Dictionary<string, LinkedList<ulong>>();
approvedSkinsCount = new Dictionary<string, int>();
NameToItemName = new Dictionary<string, string>();
ItemNameToName = new Dictionary<string, string>();
skinsLoaded = false;
skinBox = this;
if (maxPagesShown < 1) maxPagesShown = 1;
maxItemsShown = 42 * maxPagesShown;
}
private void Unload()
{
List<SBH> objs = UnityEngine.Object.FindObjectsOfType<SBH>().ToList();
if (objs.Count > 0)
foreach (SBH obj in objs)
{
if (obj.looter == null) continue;
obj.looter.EndLooting();
obj.PlayerStoppedLooting(obj.looter);
UnityEngine.Object.Destroy(obj);
}
if (Interface.Oxide.IsShuttingDown) return;
}
private void OnServerInitialized()
{
if (steamApiKey == null || steamApiKey == string.Empty || steamApiKey.Length != 32)
{
PrintWarning(_("FxvaObk pbasvt arrqf `fgrnzNcvXrl` sebz `uggcf://fgrnzpbzzhavgl.pbz/qri/ncvxrl` >> Cyhtva haybnqrq"));
Interface.Oxide.UnloadPlugin(Name);
return;
}
if (enableUsageCost)
{
if (ServerRewards != null && useServerRewards)
activeServerRewards = true;
if (Economics != null && useEconomics)
activeEconomics = true;
if (useScrap)
{
scrapItemId = ItemManager.FindItemDefinition("scrap").itemid;
activeServerRewards = false;
activeEconomics = false;
activeScrap = true;
}
if (activeServerRewards && activeEconomics)
activeEconomics = false;
if (activeServerRewards || activeEconomics || activeScrap)
activePointSystem = true;
}
if (allowStackedItems && StacksExtended)
{
_stacksExtendedExtrasDisabled = (bool) StacksExtended.CallHook("DisableExtraFeatures");
if (!_stacksExtendedExtrasDisabled)
{
Unsubscribe(nameof(CanStackItem));
Unsubscribe(nameof(OnItemSplit));
}
else
{
Subscribe(nameof(CanStackItem));
Subscribe(nameof(OnItemSplit));
}
}
foreach (Skinnable skin in Skinnable.All.ToList())
{
if (skin.Name == null || skin.Name == string.Empty) continue;
if (skin.ItemName == null || skin.ItemName == string.Empty) continue;
if (!NameToItemName.ContainsKey(skin.Name.ToLower()))
NameToItemName.Add(skin.Name.ToLower(), skin.ItemName.ToLower());
if (!ItemNameToName.ContainsKey(skin.ItemName.ToLower()))
ItemNameToName.Add(skin.ItemName.ToLower(), skin.Name.ToLower());
}
excludedSkins = excludedSkinsPre.ConvertAll(obj => Convert.ToUInt64(obj));
Puts(_("FxvaObk pbzznaq bireivrj: > fxvaobk.pzqf <"));
if (useManualAddedSkins)
{
List<ulong> s = new List<ulong>();
foreach (KeyValuePair<string, object> m in manualAddedSkinsPre)
s.AddRange((m.Value as List<object>).ConvertAll(obj => Convert.ToUInt64(obj)));
Puts(_("Dhrelvat Fgrnz sbe znahnyyl nqqrq jbexfubc fxvaf"));
CllMnlSkinsWb(s, 0);
}
else
{
GtItmSkns();
}
Initialized = true;
}
private void FnllyLdd()
{
skinsLoaded = true;
Puts(_("Cyhtva unf svavfurq vzcbegvat nyy fxvaf"));
}
private void GtItmSkns()
{
if ((Steamworks.SteamInventory.Definitions?.Length ?? 0) == 0)
{
PrintWarning("Waiting for Steamworks to update item definitions....");
Steamworks.SteamInventory.OnDefinitionsUpdated += GtItmSkns;
return;
}
Steamworks.SteamInventory.OnDefinitionsUpdated -= GtItmSkns;
int countInbuilt = 0;
foreach (ItemDefinition itemDef in ItemManager.GetItemDefinitions())
{
List<ulong> skins = new List<ulong> {0};
if (useInbuiltSkins)
skins.AddRange(ItemSkinDirectory.ForItem(itemDef).Select(skin => Convert.ToUInt64(skin.id)));
skinsCache.Add(itemDef.shortname, new LinkedList<ulong>(skins));
if (skins.Count > 1) countInbuilt += skins.Count - 1;
}
if (showLoadedSkinCounts && useInbuiltSkins) Puts(_("Ybnqrq {0} vaohvyg fxvaf"), countInbuilt);
if (useManualAddedSkins)
{
int countManual = 0;
foreach (KeyValuePair<string, HashSet<ulong>> manualskins in manualAddedSkins)
{
string shortname = manualskins.Key;
HashSet<ulong> fileids = manualskins.Value;
foreach (ulong fileid in fileids)
{
if (!skinsCache.ContainsKey(shortname))
{
skinsCache.Add(shortname, new LinkedList<ulong>());
skinsCache[shortname].AddFirst(0);
}
if (!skinsCache[shortname].Contains(fileid))
{
skinsCache[shortname].AddAfter(skinsCache[shortname].First, fileid);
countManual++;
}
}
}
if (showLoadedSkinCounts && countManual > 0) Puts(_("Ybnqrq {0} znahny nqqrq fxvaf"), countManual);
}
if (useApprovedSkins)
{
ChckApprvdSkns();
return;
}
FnllyLdd();
}
private string BldDtlsSt(List<ulong> list, int pg)
{
int st = pg * 100;
int ed = st + 100 > list.Count ? list.Count : st + 100;
string details = string.Format(_("?xrl={0}&vgrzpbhag={1}"), steamApiKey, ed - st);
for (int i = st; i < ed; i++)
details += string.Format(_("&choyvfurqsvyrvqf[{0}]={1}"), i - st, list[i]);
return details;
}
private void CllMnlSkinsWb(List<ulong> i, int pg)
{
int ttlPgs = Mathf.CeilToInt((float)i.Count / 100f) - 1;
string b = BldDtlsSt(i, pg);
try
{
webrequest.Enqueue(u1, b, (cd, res) => ServerMgr.Instance.StartCoroutine(PrfMnlSkinsWb(cd, res, i, pg, ttlPgs)), this, RequestMethod.POST);
}
catch
{
GtItmSkns();
}
}
private IEnumerator PrfMnlSkinsWb(int cd, string res, List<ulong> i, int pg, int ttlPgs)
{
if (res != null && cd == 200)
{
GtPblshdFlDtls pfd = JsonConvert.DeserializeObject<GtPblshdFlDtls>(res);
if (pfd != null && pfd.response != null && pfd.response.publishedfiledetails?.Count > 0)
{
Puts(string.Format(_("Cebprffvat jbexfubc erfcbafr. Cntr: {0} / {1}"), pg + 1, ttlPgs + 1));
foreach (GtPblshdFlDtls.Response.Publishedfiledetail det in pfd.response.publishedfiledetails)
{
if (det.tags != null && det.tags.Count > 2)
{
foreach (GtPblshdFlDtls.Tag tag in det.tags)
{
string t = tag.tag.ToLower();
string sn = string.Empty;
if (NameToItemName.ContainsKey(t)) sn = NameToItemName[t];
else continue;
skinWorkshopNames[det.publishedfileid] = det.title;
if (!manualAddedSkins.ContainsKey(sn))
manualAddedSkins.Add(sn, new HashSet<ulong>());
if (!manualAddedSkins[sn].Contains(det.publishedfileid))
manualAddedSkins[sn].Add(det.publishedfileid);
}
}
}
yield return CoroutineEx.waitForEndOfFrame;
yield return CoroutineEx.waitForEndOfFrame;
if (pg < ttlPgs)
{
CllMnlSkinsWb(i, pg + 1);
yield break;
}
}
}
if (pg < ttlPgs)
{
CllMnlSkinsWb(i, pg + 1);
yield break;
}
else GtItmSkns();
}
private void ChckApprvdSkns()
{
int count = 0;
List<int> itemSkinDirectory = Facepunch.Pool.GetList<int>();
itemSkinDirectory.AddRange(ItemSkinDirectory.Instance.skins.Select(x => x.id));
foreach (InventoryDef item in Steamworks.SteamInventory.Definitions)
{
string shortname = item.GetProperty("itemshortname");
if (string.IsNullOrEmpty(shortname) || item.Id < 100)
continue;
ulong wsid;
if (itemSkinDirectory.Contains(item.Id))
wsid = (ulong)item.Id;
else
{
if (!ulong.TryParse(item.GetProperty("workshopid"), out wsid))
continue;
}
skinWorkshopNames[wsid] = item.Name;
if (!approvedSkinsCount.ContainsKey(shortname))
approvedSkinsCount[shortname] = 0;
if (approvedSkinsLimit > 0 && approvedSkinsCount[shortname] >= approvedSkinsLimit)
{
if (!skinsCacheLimited.ContainsKey(shortname))
skinsCacheLimited[shortname] = new LinkedList<ulong>();
skinsCacheLimited[shortname].AddLast(wsid);
}
if (skinsCacheLimited.ContainsKey(shortname) && skinsCacheLimited[shortname].Contains(wsid))
continue;
if (!skinsCache.ContainsKey(shortname))
skinsCache[shortname] = new LinkedList<ulong>();
if (!skinsCache[shortname].Contains(wsid) && skinsCache[shortname].Count < maxItemsShown)
{
skinsCache[shortname].AddLast(wsid);
approvedSkinsCount[shortname]++;
count++;
}
}
Facepunch.Pool.FreeList(ref itemSkinDirectory);
if (showLoadedSkinCounts && count > 0)
{
Puts(_("Vzcbegrq {0} nccebirq fxvaf sbe '{1}' glcrf"), count, skinsCache.Where(c => c.Value.Count > 1).ToList().Count);
}
FnllyLdd();
}
//void ChckApprvdSknsWb(int cd, string res)
//{
// if (res == null || cd != 200)
// {
// FnllyLdd();
// return;
// }
// var schm = JsonConvert.DeserializeObject<Rust.Workshop.ItemSchema>(res);
// if (schm == null || !(schm is Rust.Workshop.ItemSchema) || schm.items.Length == 0)
// {
// FnllyLdd();
// return;
// }
// int count = 0;
// foreach (var item in schm.items)
// {
// if (string.IsNullOrEmpty(item.itemshortname) || string.IsNullOrEmpty(item.workshopid) || string.IsNullOrEmpty(item.workshopdownload))
// continue;
// ulong wsid = Convert.ToUInt64(item.workshopid);
// skinWorkshopNames[wsid] = item.name;
// string shortname = item.itemshortname;
// if (!approvedSkinsCount.ContainsKey(shortname))
// approvedSkinsCount[shortname] = 0;
// if (approvedSkinsLimit > 0 && approvedSkinsCount[shortname] >= approvedSkinsLimit)
// {
// if (!skinsCacheLimited.ContainsKey(shortname))
// skinsCacheLimited[shortname] = new LinkedList<ulong>();
// skinsCacheLimited[shortname].AddLast(wsid);
// }
// if (skinsCacheLimited.ContainsKey(shortname) && skinsCacheLimited[shortname].Contains(wsid))
// continue;
// if (!skinsCache.ContainsKey(shortname))
// skinsCache[shortname] = new LinkedList<ulong>();
// if (!skinsCache[shortname].Contains(wsid) && skinsCache[shortname].Count < maxItemsShown)
// {
// skinsCache[shortname].AddLast(wsid);
// approvedSkinsCount[shortname]++;
// count++;
// }
// }
// if (showLoadedSkinCounts && count > 0)
// Puts(_("Vzcbegrq {0} nccebirq fxvaf sbe '{1}' glcrf"), count, skinsCache.Where(c => c.Value.Count > 1).ToList().Count);
// FnllyLdd();
//}
[ConsoleCommand("skinbox.cmds")]
private void cmdListCmds(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
StringBuilder sb = new StringBuilder();
sb.AppendLine("\n> SkinBox command overview <");
TextTable textTable = new TextTable();
textTable.AddColumn("Command");
textTable.AddColumn("Description");
textTable.AddRow(new string[]
{"skinbox.addskin", "Does add one or multiple skin-id\'s to the manual skin list"});
textTable.AddRow(new string[]
{"skinbox.removeskin", "Does remove one or multiple skin-id\'s from the manual skin list"});
textTable.AddRow(new string[]
{"skinbox.addexcluded", "Does add one or multiple skin-id\'s to the exclusion list (for players)"});
textTable.AddRow(new string[]
{"skinbox.removeexcluded", "Does remove one or multiple skin-id\'s from the exclusion list"});
textTable.AddRow(new string[]
{"skinbox.addcollection", "Adds a whole skin-collection to the manual skins list"});
textTable.AddRow(new string[]
{"skinbox.removecollection", "Removes a whole collection from the manual skin list"});
sb.AppendLine(textTable.ToString());
SendReply(arg, sb.ToString());
}
[ConsoleCommand("skinbox.addskin")]
private void consoleAddSkin(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
if (arg.Args == null || arg.Args.Length < 1)
{
SendReply(arg, "You need to type in one or more Workshop FileId's");
return;
}
List<ulong> fileIds = new List<ulong>();
for (int i = 0; i < arg.Args.Length; i++)
{
ulong fileId = 0uL;
if (!ulong.TryParse(arg.Args[i], out fileId))
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
continue;
}
else
{
if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10)
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
continue;
}
fileIds.Add(fileId);
}
}
CallSkinsImportWeb(fileIds, arg);
}
[ConsoleCommand("skinbox.removeskin")]
private void consoleRemoveSkin(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
if (arg.Args == null || arg.Args.Length < 1)
{
SendReply(arg, "You need to type in one or more Workshop FileId's");
return;
}
List<ulong> fileIds = new List<ulong>();
for (int i = 0; i < arg.Args.Length; i++)
{
ulong fileId = 0uL;
if (!ulong.TryParse(arg.Args[i], out fileId))
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
continue;
}
else
{
if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10)
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
continue;
}
fileIds.Add(fileId);
}
}
bool doSave = false;
int removed = 0;
foreach (KeyValuePair<string, HashSet<ulong>> addedSkins in manualAddedSkins)
{
foreach (ulong fileId in fileIds)
{
if (addedSkins.Value.Contains(fileId))
{
manualAddedSkins[addedSkins.Key].Remove(fileId);
skinsCache[addedSkins.Key].Remove(fileId);
removed++;
doSave = true;
}
}
}
if (doSave)
{
Config["SkinsAdded", "SkinList"] = manualAddedSkins;
Config.Save();
SendReply(arg, $"Removed {removed} FileId's");
}
}
private void CallSkinsImportWeb(List<ulong> i, ConsoleSystem.Arg arg = null)
{
string b = string.Format(_("?xrl={0}&vgrzpbhag={1}"), steamApiKey, i.Count);
int p = 0;
foreach (ulong f in i)
{
b += string.Format(_("&choyvfurqsvyrvqf[{0}]={1}"), p, f);
p++;
}
try
{
webrequest.Enqueue(u1, b, (cd, res) => ProofSkinsImportWeb(cd, res, arg), this, RequestMethod.POST);
}
catch
{
}
}
private void ProofSkinsImportWeb(int cd, string res, ConsoleSystem.Arg arg = null)
{
if (res == null || cd != 200)
return;
GtPblshdFlDtls pfd = JsonConvert.DeserializeObject<GtPblshdFlDtls>(res);
if (pfd == null || !(pfd is GtPblshdFlDtls) || pfd.response.result == 0 || pfd.response.resultcount == 0)
return;
bool doSave = false;
foreach (GtPblshdFlDtls.Response.Publishedfiledetail det in pfd.response.publishedfiledetails)
{
if (det.tags != null && det.tags.Count > 2)
{
string sn = string.Empty;
ulong wsid = det.publishedfileid;
foreach (GtPblshdFlDtls.Tag tag in det.tags)
{
string t = tag.tag.ToLower();
if (NameToItemName.ContainsKey(t))
sn = NameToItemName[t];
else continue;
if (manualAddedSkins.ContainsKey(sn))
{
if (manualAddedSkins[sn].Contains(wsid))
{
SndRplyCl(arg, $"'{det.title} ({wsid})' was already added");
continue;
}
}
if (skinsCache.ContainsKey(sn))
{
if ((skinsCache[sn] as LinkedList<ulong>).Contains(wsid))
{
SndRplyCl(arg, $"'{det.title} ({wsid})' belongs already to approved/ranked");
continue;
}
}
if (!manualAddedSkins.ContainsKey(sn))
manualAddedSkins.Add(sn, new HashSet<ulong>());
manualAddedSkins[sn].Add(wsid);
if (!skinsCache.ContainsKey(sn))
{
skinsCache.Add(sn, new LinkedList<ulong>());
skinsCache[sn].AddLast(0);
}
skinsCache[sn].AddAfter(skinsCache[sn].First, wsid);
skinWorkshopNames[wsid] = det.title;
SndRplyCl(arg, $"'{det.title} ({wsid})' added to the list for '{sn}'");
doSave = true;
}
}
}
if (doSave)
{
Config["SkinsAdded", "SkinList"] = manualAddedSkins;
Config.Save();
}
}
[ConsoleCommand("skinbox.addexcluded")]
private void consoleAddExcluded(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
if (arg.Args == null || arg.Args.Length < 1)
{
SendReply(arg, "You need to type in one or more Workshop FileId's");
return;
}
List<ulong> fileIds = new List<ulong>();
for (int i = 0; i < arg.Args.Length; i++)
{
ulong fileId = 0uL;
if (!ulong.TryParse(arg.Args[i], out fileId))
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
continue;
}
else
{
if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10)
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
continue;
}
fileIds.Add(fileId);
}
}
int countAdded = 0;
foreach (ulong fileId in fileIds)
if (!excludedSkins.Contains(fileId))
{
excludedSkins.Add(fileId);
countAdded++;
}
if (countAdded > 0)
{
Config["SkinsExcluded", "SkinList"] = excludedSkins;
Config.Save();
SendReply(arg, $"Added {countAdded} skins to exclusion list");
}
}
[ConsoleCommand("skinbox.removeexcluded")]
private void consoleRemoveExcluded(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
if (arg.Args == null || arg.Args.Length < 1)
{
SendReply(arg, "You need to type in one or more Workshop FileId's");
return;
}
List<ulong> fileIds = new List<ulong>();
for (int i = 0; i < arg.Args.Length; i++)
{
ulong fileId = 0uL;
if (!ulong.TryParse(arg.Args[i], out fileId))
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
continue;
}
else
{
if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10)
{
SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
continue;
}
fileIds.Add(fileId);
}
}
int countRemoved = 0;
foreach (ulong fileId in fileIds)
if (excludedSkins.Contains(fileId))
{
excludedSkins.Remove(fileId);
countRemoved++;
}
if (countRemoved > 0)
{
Config["SkinsExcluded", "SkinList"] = excludedSkins;
Config.Save();
SndRplyCl(arg, $"Removed {countRemoved} skins from exclusion");
}
}
[ConsoleCommand("skinbox.addcollection")]
private void consoleAddCollection(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
if (arg.Args == null || arg.Args.Length < 1)
{
SendReply(arg, "You need to type in a valid collection id");
return;
}
ulong collId = 0;
if (!ulong.TryParse(arg.Args[0], out collId))
{
SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' is not a number");
return;
}
else
{
if (arg.Args[0].Length < 9 || arg.Args[0].Length > 10)
{
SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' has not 9/10-Digits");
return;
}
}
string b = string.Format(_("?xrl={0}&pbyyrpgvbapbhag=1&choyvfurqsvyrvqf[0]={1}"), steamApiKey, arg.Args[0]);
try
{
webrequest.Enqueue(u2, b, (cd, res) => PstCllbckAdd(cd, res, arg), this, RequestMethod.POST);
}
catch
{
SndRplyCl(arg, "Steam webrequest failed!");
}
}
public void PstCllbckAdd(int cd, string res, ConsoleSystem.Arg arg = null)
{
if (res == null || cd != 200)
{
SndRplyCl(arg, "Steam webrequest failed by wrong response!");
return;
}
GtCllctnDtls col = JsonConvert.DeserializeObject<GtCllctnDtls>(res);
if (col == null || !(col is GtCllctnDtls))
{
SndRplyCl(arg, "No Collection data received!");
return;
}
if (col.response.resultcount == 0 || col.response.collectiondetails == null ||
col.response.collectiondetails.Count == 0 || col.response.collectiondetails[0].result != 1)
{
SndRplyCl(arg, "The Steam collection could not be found!");
return;
}
List<ulong> fileIds = new List<ulong>();
foreach (GtCllctnDtls.Response.Collectiondetail.Child child in col.response.collectiondetails[0].children)
try
{
fileIds.Add(Convert.ToUInt64(child.publishedfileid));
}
catch
{
}
if (fileIds.Count == 0)
{
SndRplyCl(arg, "No skin numbers found. Workshop search cancelled.");
return;
}
CallSkinsImportWeb(fileIds, arg);
}
[ConsoleCommand("skinbox.removecollection")]
private void consoleRemoveCollection(ConsoleSystem.Arg arg)
{
if (arg.Connection != null && (arg.Connection.authLevel < 2 && !permission.UserHasPermission(arg.Connection.userid.ToString(), permissionAdmin))) return;
if (arg.Args == null || arg.Args.Length < 1)
{
SendReply(arg, "You need to type in a valid collection id");
return;
}
ulong collId = 0;
if (!ulong.TryParse(arg.Args[0], out collId))
{
SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' is not a number");
return;
}
else
{
if (arg.Args[0].Length < 9 || arg.Args[0].Length > 10)
{
SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' has not 9/10-Digits");
return;
}
}
string b = string.Format(_("?xrl={0}&pbyyrpgvbapbhag=1&choyvfurqsvyrvqf[0]={1}"), steamApiKey, arg.Args[0]);
try
{
webrequest.Enqueue(u2, b, (cd, res) => PostCallbackRemove(cd, res, arg), this, RequestMethod.POST);
}
catch
{
SndRplyCl(arg, "Steam webrequest failed!");
}
}
public void PostCallbackRemove(int cd, string res, ConsoleSystem.Arg arg = null)
{
if (res == null || cd != 200)
{
SndRplyCl(arg, "Steam webrequest failed by wrong response!");
return;
}
GtCllctnDtls col = JsonConvert.DeserializeObject<GtCllctnDtls>(res);
if (col == null || !(col is GtCllctnDtls))
{
SndRplyCl(arg, "No Collection data received!");
return;
}
if (col.response.resultcount == 0 || col.response.collectiondetails == null ||
col.response.collectiondetails.Count == 0 || col.response.collectiondetails[0].result != 1)
{
SndRplyCl(arg, "The Steam collection could not be found!");
return;
}
List<ulong> fileIds = new List<ulong>();
foreach (GtCllctnDtls.Response.Collectiondetail.Child child in col.response.collectiondetails[0].children)
try
{
fileIds.Add(Convert.ToUInt64(child.publishedfileid));
}
catch
{
}
if (fileIds.Count == 0)
{
SndRplyCl(arg, "No skin numbers found. Workshop search cancelled.");
return;
}
int removed = 0;
foreach (KeyValuePair<string, HashSet<ulong>> addSkins in new Dictionary<string, HashSet<ulong>>(manualAddedSkins))
{
foreach (ulong skin in addSkins.Value.ToList())
{
if (fileIds.Contains(skin))
{
manualAddedSkins[addSkins.Key].Remove(skin);
if (skinsCache.ContainsKey(addSkins.Key)) skinsCache[addSkins.Key].Remove(skin);
removed++;
}
}
}
if (removed > 0)
{
SndRplyCl(arg, $"Removed '{removed}' manual skins by collection remove.");
Config["SkinsAdded", "SkinList"] = manualAddedSkins;
Config.Save();
}
else
{
SndRplyCl(arg, $"No manual skins to remove by collection remove.");
}
}
[ConsoleCommand("skinbox.open")]
private void consoleSkinboxOpen(ConsoleSystem.Arg arg)
{
if (arg == null) return;
if (arg.Connection == null)
{
if (arg.Args == null || arg.Args.Length == 0)
{
SendReply(arg, $"'skinbox.open' cmd needs a passed steamid ");
return;
}
ulong argId = 0uL;
if (!ulong.TryParse(arg.Args[0], out argId))
{
SendReply(arg, $"'skinbox.open' cmd for '{arg.Args[0]}' failed (no valid number)");
return;
}
BasePlayer argPlayer = BasePlayer.FindByID(argId);
if (argPlayer == null)
{
SendReply(arg, $"'skinbox.open' cmd for userID '{argId}' failed (player not found)");
return;
}
if (!argPlayer.inventory.loot.IsLooting()) OpnSknBx(argPlayer);
}
else if (arg.Connection != null && arg.Connection.player != null)
{
BasePlayer player = arg.Player();
if (player.inventory.loot.IsLooting()) return;
if (!(player.IsAdmin || player.net.connection.authLevel >= accessOverrideAuthLevel) &&
!permission.UserHasPermission(player.UserIDString, permissionUse))
{
player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
return;
}
if (!ChckOpnBlnc(player)) return;
if (enableCooldown && !(cooldownOverrideAdmin &&
(player.IsAdmin ||
player.net.connection.authLevel >= cooldownOverrideAuthLevel)))
{
DateTime now = DateTime.UtcNow;
DateTime time;
string key = player.UserIDString + "-box";
if (cooldownTimes.TryGetValue(key, out time))
if (time > now.AddSeconds(-cooldownBox))
{
player.ChatMessage(string.Format(lang.GetMessage("CooldownTime", this, player.UserIDString),
(time - now.AddSeconds(-cooldownBox)).Seconds));
return;
}
}
OpnSknBx(player);
}
}
private void cmdSknBx(BasePlayer player, string command, string[] args)
{
if (player.inventory.loot.IsLooting()) return;
if (!(player.IsAdmin || player.net.connection.authLevel >= accessOverrideAuthLevel) &&
!permission.UserHasPermission(player.UserIDString, permissionUse))
{
player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
return;
}
if (!ChckOpnBlnc(player)) return;
if (enableCooldown && !(cooldownOverrideAdmin &&
(player.IsAdmin || player.net.connection.authLevel >= cooldownOverrideAuthLevel)))
{
DateTime now = DateTime.UtcNow;
DateTime time;
string key = player.UserIDString + "-box";
if (cooldownTimes.TryGetValue(key, out time))
if (time > now.AddSeconds(-cooldownBox))
{
player.ChatMessage(string.Format(lang.GetMessage("CooldownTime", this, player.UserIDString),
(time - now.AddSeconds(-cooldownBox)).Seconds));
return;
}
}
timer.Once(0.2f, () => { OpnSknBx(player); });
}
public bool ChckOpnBlnc(BasePlayer player)
{
if (!activePointSystem || costBoxOpen <= 0 || player.IsAdmin && costExcludeAdmins ||
costExcludePermEnabled && permission.UserHasPermission(player.UserIDString, costExcludePerm))
return true;
int playerMoney = 0;
if (activeServerRewards)
playerMoney = (int)(Interface.Oxide.CallHook("CheckPoints", player.userID) ?? 0);
if (activeEconomics)
playerMoney = Convert.ToInt32((double)(Interface.Oxide.CallHook("Balance", player.UserIDString) ?? 0.0));
if (activeScrap)
playerMoney = player.inventory.GetAmount(scrapItemId);
if (playerMoney < costBoxOpen)
{
player.ChatMessage(string.Format(lang.GetMessage(activeServerRewards ? "NotEnoughBalanceOpenRP" : activeEconomics ? "NotEnoughBalanceOpenEco" : "NotEnoughBalanceOpenScrap", this, player.UserIDString),
costBoxOpen));
return false;
}
if (activeServerRewards)
Interface.Oxide.CallHook("TakePoints", player.userID, costBoxOpen);
if (activeEconomics)
Interface.Oxide.CallHook("Withdraw", player.userID, Convert.ToDouble(costBoxOpen));
if (activeScrap)
player.inventory.Take(null, scrapItemId, costBoxOpen);
return true;
}
public bool ChckSknBlnc(BasePlayer player, Item item)
{
if (!activePointSystem || player.IsAdmin && costExcludeAdmins || costExcludePermEnabled && permission.UserHasPermission(player.UserIDString, costExcludePerm))
return true;
int playerMoney = 0;
if (activeServerRewards)
playerMoney = (int) (Interface.Oxide.CallHook("CheckPoints", player.userID) ?? 0);
if (activeEconomics)
playerMoney = Convert.ToInt32((double) (Interface.Oxide.CallHook("Balance", player.UserIDString) ?? 0.0));
if (activeScrap)
playerMoney = player.inventory.GetAmount(scrapItemId);
bool hasBalance = false;
int getCost = 0;
switch (item.info.category.ToString())
{
case "Weapon":
case "Tool":
if (costWeapon <= 0 || playerMoney > costWeapon) hasBalance = true;
getCost = costWeapon;
break;
case "Attire":
if (costPlayerwearable <= 0 || playerMoney > costPlayerwearable) hasBalance = true;
getCost = costPlayerwearable;
break;
case "Items":
case "Construction":
if (costDeployable <= 0 || playerMoney > costDeployable) hasBalance = true;
getCost = costDeployable;
break;
default:
hasBalance = true;
break;
}
if (!hasBalance)
{
player.ChatMessage(string.Format(lang.GetMessage(activeServerRewards ? "NotEnoughBalanceUseRP" : activeEconomics ? "NotEnoughBalanceUseEco" : "NotEnoughBalanceUseScrap", this, player.UserIDString),
getCost, item.info.displayName.translated));
return false;
}
return true;
}
public bool WthdrwBlnc(BasePlayer player, Item item)
{
if (!activePointSystem || player.IsAdmin && costExcludeAdmins || costExcludePermEnabled &&
permission.UserHasPermission(player.UserIDString, costExcludePerm)) return true;
int getCost = 0;
switch (item.info.category.ToString())
{
case "Weapon":
case "Tool":
getCost = costWeapon;
break;
case "Attire":
getCost = costPlayerwearable;
break;
case "Items":
case "Construction":
getCost = costDeployable;
break;
default: break;
}
bool hadMoney = false;
if (activeServerRewards && (bool) Interface.Oxide.CallHook("TakePoints", player.userID, getCost))
hadMoney = true;
if (activeEconomics && (bool) Interface.Oxide.CallHook("Withdraw", player.userID, Convert.ToDouble(getCost)))
hadMoney = true;
if (player.inventory.GetAmount(scrapItemId) >= getCost)
{
player.inventory.Take(null, scrapItemId, getCost);
hadMoney = true;
}
if (!hadMoney)
{
player.ChatMessage(string.Format(lang.GetMessage(activeServerRewards ? "NotEnoughBalanceTakeRP" : activeEconomics ? "NotEnoughBalanceTakeEco" : "NotEnoughBalanceTakeScrap", this, player.UserIDString),
item.info.displayName.translated));
return false;
}
return true;
}
internal class SBH : FacepunchBehaviour
{
public bool isCreating;
public bool isBlocked;
public bool isEmptied;
public int itemId;
public int itemAmount;
public Item currentItem;
public BasePlayer looter;
public ItemContainer loot;
public BaseEntity entityOwner;
public ulong skinId;
public int currentPage;
public int totalPages;
public LinkedList<ulong> itemSkins;
public int skinsTotal;
public int perPageTotal;
public int maxPages;
public bool refundItem;
public int lastItemAmount;
public Item lastItemRemoved;
private void Awake()
{
isCreating = false;
isBlocked = false;
isEmptied = false;
skinId = 0uL;
currentPage = 1;
totalPages = 1;
skinsTotal = 1;
perPageTotal = 1;
itemAmount = 1;
maxPages = skinBox.maxPagesShown;
itemSkins = new LinkedList<ulong>();
}
public void ShwUi()
{
if (totalPages > 1 && maxPages > 1)
{
int p = Math.Min(maxPages, totalPages);
skinBox.CrtUi(looter, currentPage, p);
}
}
public void ClsUi()
{
skinBox.DstryUi(looter);
}
public void PgNxt()
{
if (totalPages > 1 && currentPage < maxPages && currentPage < totalPages && !isCreating)
{
currentPage++;
FllSknBx(currentPage);
ShwUi();
}
}
public void PgPrv()
{
if (totalPages > 1 && currentPage > 1 && !isCreating)
{
currentPage--;
FllSknBx(currentPage);
ShwUi();
}
}
public void StrtNwItm(ItemContainer container, Item item)
{
isBlocked = true;
currentItem = item;
lastItemAmount = 0;
lastItemRemoved = null;
itemAmount = item.amount;
itemId = item.info.itemid;
skinId = item.skin;
string shortname = currentItem.info.shortname == _("evsyr.ye300")
? _("ye300.vgrz")
: currentItem.info.shortname;
itemSkins = new LinkedList<ulong>(skinBox.skinsCache[shortname] as LinkedList<ulong>);
itemSkins.Remove(0uL);
itemSkins.Remove(skinId);
skinsTotal = itemSkins.Count;
perPageTotal = skinId == 0uL ? 41 : 40;
currentPage = 1;
totalPages = Mathf.CeilToInt(skinsTotal / (float) perPageTotal);
loot = container;
entityOwner = loot.entityOwner;
}
public void FllSknBx(int page = 1)
{
isCreating = true;
string origname = currentItem.info.shortname;
bool hasCondition = currentItem.hasCondition;
float condition = currentItem.condition;
float maxCondition = currentItem.maxCondition;
bool isWeapon = currentItem.GetHeldEntity() is BaseProjectile;
bool hasMods = false;
int contents = 0;
int capacity = 0;
ItemDefinition ammoType = null;
Dictionary<int, float> itemMods = new Dictionary<int, float>();
if (isWeapon)
{
contents = (currentItem.GetHeldEntity() as BaseProjectile).primaryMagazine.contents;
capacity = (currentItem.GetHeldEntity() as BaseProjectile).primaryMagazine.capacity;
ammoType = (currentItem.GetHeldEntity() as BaseProjectile).primaryMagazine.ammoType;
if (currentItem.contents != null && currentItem.contents.itemList.Count > 0)
{
hasMods = true;
foreach (Item mod in currentItem.contents.itemList)
itemMods.Add(mod.info.itemid, mod.condition);
}
}
isEmptied = false;
if (currentItem.contents != null && currentItem.contents.itemList.Count > 0)
{
Item[] array = currentItem.contents.itemList.ToArray();
for (int i = 0; i < array.Length; i++)
{
if (array[i].info.category == ItemCategory.Weapon) continue;
Item item = array[i];
looter.inventory.GiveItem(item, null);
}
}
skinBox.RmvItm(loot, currentItem);
skinBox.ClrCntnr(loot);
int startIndex = page * perPageTotal - perPageTotal;
int amount = page < totalPages ? perPageTotal : skinsTotal - ((page - 1) * perPageTotal);// page == totalPages ? lastPageCount : perPageTotal;
List<ulong> skins = new List<ulong> {0uL};
if (skinId != 0uL) skins.Add(skinId);
if (maxPages > 1 && totalPages > 1)
skins.AddRange(itemSkins.ToList().GetRange(startIndex, amount));
else skins.AddRange(itemSkins.ToList());
loot.capacity = skins.Count();
ItemDefinition itemDef = ItemManager.FindItemDefinition(origname);
loot.capacity = Mathf.Min(42, skins.Count);
foreach (ulong skin in skins)
{
if (loot.IsFull()) break;
if (skinBox.excludedSkins.Contains(skin) && looter.net.connection.authLevel < skinBox.exludedSkinsAuthLevel)
continue;
Item newItem = ItemManager.Create(itemDef, 1, skin);
if (skinBox.skinWorkshopNames.ContainsKey(skin)) newItem.name = skinBox.skinWorkshopNames[skin];
if (hasCondition)
{
newItem.condition = condition;
newItem.maxCondition = maxCondition;
}
if (isWeapon)
{
BaseProjectile gun = newItem.GetHeldEntity() as BaseProjectile;
gun.primaryMagazine.contents = contents;
gun.primaryMagazine.capacity = capacity;
gun.primaryMagazine.ammoType = ammoType;
if (hasMods)
{
foreach (KeyValuePair<int, float> mod in itemMods)
{
Item newMod = ItemManager.CreateByItemID((int) mod.Key, 1);
newMod.condition = Convert.ToSingle(mod.Value);
newMod.MoveToContainer(newItem.contents, -1, false);
}
newItem.contents.SetFlag(ItemContainer.Flag.IsLocked, true);
newItem.contents.SetFlag(ItemContainer.Flag.NoItemInput, true);
newItem.contents.MarkDirty();
}
}
newItem.MarkDirty();
skinBox.InsrtItm(loot, newItem);
}
isCreating = false;
loot.MarkDirty();
}
public void PlayerStoppedLooting(BasePlayer player)
{
if (!isEmptied && currentItem != null)
{
isEmptied = true;
if (refundItem) player.GiveItem(currentItem);
}
if (!GetComponent<BaseEntity>().IsDestroyed)
GetComponent<BaseEntity>().Kill(BaseNetworkable.DestroyMode.None);
if (skinBox.enableCooldown) skinBox.cooldownTimes[player.UserIDString + "-box"] = DateTime.UtcNow;
}
private void OnDestroy()
{
skinBox.DstryUi(looter);
skinBox.activeSkinBoxes.Remove(looter.userID);
if (!isEmptied && currentItem != null)
{
isEmptied = true;
looter.GiveItem(currentItem);
}
looter.EndLooting();
}
}
private void OpnSknBx(BasePlayer player, bool refundItem = true)
{
BaseEntity skinBox = GameManager.server.CreateEntity(StringPool.Get(4080262419),
player.transform.position - new Vector3(0, 250f + UnityEngine.Random.Range(-25f, 25f), 0));
(skinBox as BaseNetworkable).limitNetworking = true;
UnityEngine.Object.Destroy(skinBox.GetComponent<DestroyOnGroundMissing>());
UnityEngine.Object.Destroy(skinBox.GetComponent<GroundWatch>());
skinBox.Spawn();
SBH lootHandler = skinBox.gameObject.AddComponent<SBH>();
lootHandler.looter = player;
lootHandler.refundItem = refundItem;
StorageContainer container = skinBox.GetComponent<StorageContainer>();
if (!allowStackedItems)
{
container.maxStackSize = 1;
container.inventory.maxStackSize = 1;
}
container.inventory.capacity = 1;
container.SetFlag(BaseEntity.Flags.Open, true, false);
if (QuickSort && hideQuickSort) StrtLtngEntty(player.inventory.loot, container);
else player.inventory.loot.StartLootingEntity(container, false);
player.inventory.loot.AddContainer(container.inventory);
player.inventory.loot.SendImmediate();
player.ClientRPCPlayer(null, player, _("ECP_BcraYbbgCnary"), _("trarevpynetr"));
container.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
activeSkinBoxes.Add(player.userID, lootHandler);
}
public void StrtLtngEntty(PlayerLoot loot, BaseEntity targetEntity)
{
loot.Clear();
if (!targetEntity) return;
loot.PositionChecks = false;
loot.entitySource = targetEntity;
loot.itemSource = null;
loot.MarkDirty();
}
public void ClrCntnr(ItemContainer container)
{
while (container.itemList.Count > 0)
{
Item removeItem = container.itemList[0];
//if (removeItem.contents?.itemList?.Count > 0)
// ClrCntnr(removeItem.contents);
RmvItm(container, removeItem);
//removeItem.RemoveFromContainer();
removeItem.Remove(0f);
}
}
private object CanAcceptItem(ItemContainer container, Item item)
{
if (container.entityOwner == null) return null;
SBH lootHandler;
if ((lootHandler = container.entityOwner.GetComponent<SBH>()) == null) return null;
string shortname = item.info.shortname == _("evsyr.ye300") ? _("ye300.vgrz") : item.info.shortname;
if (lootHandler.isCreating || lootHandler.isBlocked ||
enableCustomPerms && !ChckItmPrms(lootHandler.looter, item) || item.isBroken ||
!skinsCache.ContainsKey(shortname) || (skinsCache[shortname] as LinkedList<ulong>).Count <= 1 ||
!ChckSknBlnc(lootHandler.looter, item)) return ItemContainer.CanAcceptResult.CannotAccept;
return null;
}
public bool ChckItmPrms(BasePlayer player, Item item)
{
string category = item.info.category.ToString();
switch (category)
{
case "Weapon":
if (permission.UserHasPermission(player.UserIDString, permCustomWeapon)) return true;
break;
case "Tool":
if (permission.UserHasPermission(player.UserIDString, permCustomWeapon)) return true;
break;
case "Attire":
if (permission.UserHasPermission(player.UserIDString, permCustomPlayerwearable)) return true;
break;
case "Items":
if (permission.UserHasPermission(player.UserIDString, permCustomDeployable)) return true;
break;
case "Construction":
if (permission.UserHasPermission(player.UserIDString, permCustomDeployable)) return true;
break;
default: return true;
}
return false;
}
private void OnItemAddedToContainer(ItemContainer container, Item item)
{
if (container == null || item == null)
return;
if (container.entityOwner != null)
{
SBH lootHandler = container.entityOwner.GetComponent<SBH>();
if (lootHandler == null || lootHandler.isBlocked)
return;
lootHandler.StrtNwItm(container, item);
lootHandler.FllSknBx();
if (maxPagesShown > 1)
lootHandler.ShwUi();
}
}
private object CanMoveItem(Item movedItem, PlayerInventory inventory, uint targetContainerID, int targetSlot, int amount)
{
if (movedItem.parent?.entityOwner != null)
{
SBH lootHandler = movedItem.parent?.entityOwner?.GetComponent<SBH>();
if (lootHandler != null)
{
if (lootHandler.itemAmount > 1)
{
ItemContainer targetContainer = inventory.FindContainer(targetContainerID);
if (targetContainer != null && targetContainer.GetSlot(targetSlot) != null)
return false;
}
}
}
return null;
}
public bool InsrtItm(ItemContainer container, Item item, bool mark = false)
{
if (container.itemList.Contains(item)) return false;
if (container.IsFull()) return false;
container.itemList.Add(item);
item.parent = container;
if (!container.FindPosition(item)) return false;
if (mark) container.MarkDirty();
if (container.onItemAddedRemoved != null) container.onItemAddedRemoved(item, true);
return true;
}
public bool RmvItm(ItemContainer container, Item item, bool mark = false)
{
if (!container.itemList.Contains(item))
return false;
if (container.onPreItemRemove != null)
container.onPreItemRemove(item);
container.itemList.Remove(item);
item.parent = null;
if (mark)
container.MarkDirty();
if (container.onItemAddedRemoved != null)
container.onItemAddedRemoved(item, false);
return true;
}
private void OnItemRemovedFromContainer(ItemContainer container, Item item)
{
if (container == null || item == null || container.entityOwner == null)
return;
SBH lootHandler = container.entityOwner.GetComponent<SBH>();
if (lootHandler == null || !lootHandler.isBlocked)
return;
if (item.GetHeldEntity() is BaseProjectile && item.contents != null)
{
item.contents.SetFlag(ItemContainer.Flag.IsLocked, false);
item.contents.SetFlag(ItemContainer.Flag.NoItemInput, false);
}
if (lootHandler.itemAmount > 1)
{
item.amount = lootHandler.itemAmount;
item.MarkDirty();
lootHandler.lastItemRemoved = item;
lootHandler.lastItemAmount = lootHandler.itemAmount;
lootHandler.itemAmount = 1;
}
ClrCntnr(container);
if (lootHandler.currentItem != null)
{
lootHandler.currentItem.Remove(0f);
lootHandler.currentItem = null;
}
container.MarkDirty();
lootHandler.isEmptied = true;
lootHandler.ClsUi();
container.capacity = 1;
if (item.skin == 0uL)
{
lootHandler.skinId = 0uL;
lootHandler.isBlocked = false;
return;
}
if (!WthdrwBlnc(lootHandler.looter, item))
{
item.skin = lootHandler.skinId;
if (item.GetHeldEntity()) item.GetHeldEntity().skinID = lootHandler.skinId;
item.MarkDirty();
}
if (enableCooldown && activateAfterSkinTaken &&
!(cooldownOverrideAdmin && (lootHandler.looter.IsAdmin ||
lootHandler.looter.net.connection.authLevel >= cooldownOverrideAuthLevel)
) && item.skin != lootHandler.skinId)
{
lootHandler.looter.EndLooting();
skinBox.cooldownTimes[lootHandler.looter.UserIDString + "-box"] = DateTime.UtcNow;
}
lootHandler.skinId = 0uL;
lootHandler.isBlocked = false;
}
public void UnsbscrbSplt()
{
Unsubscribe(nameof(OnItemSplit));
Unsubscribe(nameof(CanStackItem));
}
public void SbscrbSplt()
{
Subscribe(nameof(OnItemSplit));
Subscribe(nameof(CanStackItem));
}
public void SndRplyCl(ConsoleSystem.Arg arg, string format)
{
if (arg != null && arg.Connection != null) SendReply(arg, format);
Puts(format);
}
private static string _(string i)
{
return !string.IsNullOrEmpty(i)
? new string(i.Select(x =>
x >= 'a' && x <= 'z' ? (char) ((x - 'a' + 13) % 26 + 'a') :
x >= 'A' && x <= 'Z' ? (char) ((x - 'A' + 13) % 26 + 'A') : x).ToArray())
: i;
}
public void DstryUi(BasePlayer player)
{
CuiHelper.DestroyUi(player, "SkinBoxUI");
}
public void CrtUi(BasePlayer player, int page = 1, int total = 1)
{
string panelName = "SkinBoxUI";
CuiHelper.DestroyUi(player, panelName);
string contentColor = "0.7 0.7 0.7 1.0";
string buttonColor = "0.75 0.75 0.75 0.1";
string buttonTextColor = "0.77 0.68 0.68 1";
CuiElementContainer result = new CuiElementContainer();
string rootPanelName =
result.Add(
new CuiPanel
{
Image = new CuiImageComponent {Color = "0 0 0 0"},
RectTransform = {AnchorMin = "0.9505 0.15", AnchorMax = "0.99 0.6"}
}, "Hud.Menu", panelName);
result.Add(
new CuiPanel
{
Image = new CuiImageComponent {Color = "0.65 0.65 0.65 0.06"},
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"}
}, rootPanelName);
result.Add(
new CuiButton
{
RectTransform = {AnchorMin = "0.025 0.7", AnchorMax = "0.975 1.0"},
Button = {Command = _("fxvaobk.cntrceri"), Color = buttonColor},
Text = {Align = TextAnchor.MiddleCenter, Text = "◀", Color = buttonTextColor, FontSize = 50}
}, rootPanelName);
result.Add(
new CuiLabel
{
RectTransform = {AnchorMin = "0.025 0.3", AnchorMax = "0.975 0.7"},
Text =
{
Align = TextAnchor.MiddleCenter, Text = $"{page}\nof\n{total}", Color = contentColor,
FontSize = 20
}
}, rootPanelName);
result.Add(
new CuiButton
{
RectTransform = {AnchorMin = "0.025 0", AnchorMax = "0.975 0.3"},
Button = {Command = _("fxvaobk.cntrarkg"), Color = buttonColor},
Text = {Align = TextAnchor.MiddleCenter, Text = "▶", Color = buttonTextColor, FontSize = 50}
}, rootPanelName);
CuiHelper.AddUi(player, result);
}
[ConsoleCommand("skinbox.pagenext")]
private void cmdPageNext(ConsoleSystem.Arg arg)
{
if (maxPagesShown <= 1 || arg == null || arg.Connection == null) return;
BasePlayer player = arg.Connection?.player as BasePlayer;
if (player == null) return;
if (activeSkinBoxes.ContainsKey(player.userID)) activeSkinBoxes[player.userID].PgNxt();
}
[ConsoleCommand("skinbox.pageprev")]
private void cmdPagePrev(ConsoleSystem.Arg arg)
{
if (maxPagesShown <= 1 || arg == null || arg.Connection == null) return;
BasePlayer player = arg.Connection?.player as BasePlayer;
if (player == null) return;
if (activeSkinBoxes.ContainsKey(player.userID)) activeSkinBoxes[player.userID].PgPrv();
}
private bool IsSkinBoxPlayer(ulong playerId) => activeSkinBoxes.ContainsKey(playerId);
private void OnPluginUnloaded(Plugin name)
{
if (Initialized && name.Name == _("FgnpxfRkgraqrq")) ChckSbscrptns(true);
}
private void OnPluginLoaded(Plugin name)
{
if (Initialized && name.Name == _("FgnpxfRkgraqrq")) ChckSbscrptns(false);
}
public void ChckSbscrptns(bool wasUnload)
{
if (!allowStackedItems) return;
if (wasUnload)
{
_stacksExtendedExtrasDisabled = false;
Subscribe(nameof(CanStackItem));
Subscribe(nameof(OnItemSplit));
}
else
{
_stacksExtendedExtrasDisabled = (bool) StacksExtended.CallHook("DisableExtraFeatures");
if (!_stacksExtendedExtrasDisabled)
{
Unsubscribe(nameof(CanStackItem));
Unsubscribe(nameof(OnItemSplit));
}
else
{
Subscribe(nameof(CanStackItem));
Subscribe(nameof(OnItemSplit));
}
}
}
private object OnItemSplit(Item thisI, int split_Amount)
{
if (thisI.skin == 0uL) return null;
Item item = null;
item = ItemManager.CreateByItemID(thisI.info.itemid, 1, thisI.skin);
if (item != null)
{
thisI.amount -= split_Amount;
thisI.MarkDirty();
item.amount = split_Amount;
item.OnVirginSpawn();
if (thisI.IsBlueprint()) item.blueprintTarget = thisI.blueprintTarget;
if (thisI.hasCondition) item.condition = thisI.condition;
item.MarkDirty();
return item;
}
return null;
}
private object CanStackItem(Item thisI, Item item)
{
if (thisI.skin == item.skin) return null;
if (thisI.skin != item.skin) return false;
if (thisI.skin == item.skin)
{
if (thisI.hasCondition && item.hasCondition)
{
if (item.condition != thisI.condition)
return false;
}
return true;
}
return null;
}
private string u1 = _("uggcf://ncv.fgrnzcbjrerq.pbz/VFgrnzErzbgrFgbentr/TrgChoyvfurqSvyrQrgnvyf/i1/");
private string u2 = _("uggcf://ncv.fgrnzcbjrerq.pbz/VFgrnzErzbgrFgbentr/TrgPbyyrpgvbaQrgnvyf/i1/");
//private string u3 = _("uggc://f3.nznmbanjf.pbz/f3.cynlehfg.pbz/vpbaf/vairagbel/ehfg/fpurzn.wfba");
public class GtPblshdFlDtls
{
[JsonProperty("response")] public Response response;
public class Tag
{
[JsonProperty("tag")] public string tag;
}
public class Response
{
[JsonProperty("result")] public int result;
[JsonProperty("resultcount")] public int resultcount;
[JsonProperty("publishedfiledetails")] public List<Publishedfiledetail> publishedfiledetails;
public class Publishedfiledetail
{
[JsonProperty("publishedfileid")] public ulong publishedfileid;
[JsonProperty("result")] public int result;
[JsonProperty("creator")] public string creator;
[JsonProperty("creator_app_id")] public int creator_app_id;
[JsonProperty("consumer_app_id")] public int consumer_app_id;
[JsonProperty("filename")] public string filename;
[JsonProperty("file_size")] public int file_size;
[JsonProperty("preview_url")] public string preview_url;
[JsonProperty("hcontent_preview")] public string hcontent_preview;
[JsonProperty("title")] public string title;
[JsonProperty("description")] public string description;
[JsonProperty("time_created")] public int time_created;
[JsonProperty("time_updated")] public int time_updated;
[JsonProperty("visibility")] public int visibility;
[JsonProperty("banned")] public int banned;
[JsonProperty("ban_reason")] public string ban_reason;
[JsonProperty("subscriptions")] public int subscriptions;
[JsonProperty("favorited")] public int favorited;
[JsonProperty("lifetime_subscriptions")]
public int lifetime_subscriptions;
[JsonProperty("lifetime_favorited")] public int lifetime_favorited;
[JsonProperty("views")] public int views;
[JsonProperty("tags")] public List<Tag> tags;
}
}
}
public class GtCllctnDtls
{
[JsonProperty("response")] public Response response;
public class Response
{
[JsonProperty("result")] public int result;
[JsonProperty("resultcount")] public int resultcount;
[JsonProperty("collectiondetails")] public List<Collectiondetail> collectiondetails;
public class Collectiondetail
{
[JsonProperty("publishedfileid")] public string publishedfileid;
[JsonProperty("result")] public int result;
[JsonProperty("children")] public List<Child> children;
public class Child
{
[JsonProperty("publishedfileid")] public string publishedfileid;
[JsonProperty("sortorder")] public int sortorder;
[JsonProperty("filetype")] public int filetype;
}
}
}
}
}
}