{
private const string commandWipe = "kits.wipe";
private const string commandConstant = "kits.core";
private const string commandGiveConstant = "kits.give";
private const string commandConvertConstant = "kits.convert";
private class KitInfo {
public DateTime lastUse;
public int uses;
}
private void Init() {
foreach (var kit in config.kits) {
if (permission.PermissionExists(kit.permission) == false) {
permission.RegisterPermission(kit.permission, this);
}
}
foreach (var command in config.commands) {
cmd.AddChatCommand(command, this, nameof(cmdControlChat));
cmd.AddConsoleCommand(command, this, nameof(cmdControlConsole));
}
cmd.AddConsoleCommand(commandConstant, this, nameof(cmdControlConsole));
cmd.AddConsoleCommand(commandWipe, this, nameof(cmdControlConsole));
cmd.AddConsoleCommand(commandGiveConstant, this, nameof(cmdControlConsole));
cmd.AddConsoleCommand(commandConvertConstant, this, nameof(cmdControlConsole));
}
private void OnServerInitialized() {
LoadData();
timer.Once(3f, LoadImages);
}
private void Unload() {
SaveData();
}
private void cmdControlConsole(ConsoleSystem.Arg arg) {
var args = arg.Args ?? new string[] {
};
var command = arg.cmd?.FullName;
if (command == commandWipe && arg.IsAdmin == true) {
Data = new PluginData();
SaveData();
SendReply(arg, "Cooldown data was cleared for all!");
return;
}
if (command == commandGiveConstant && arg.IsAdmin == true) {
var playerName = args.Length > 0 ? args[0] : "null";
var kitName = args.Length > 1 ? args[1] : "null";
var player = FindPlayer(playerName);
if (player == null) {
SendReply(arg, $"Can't find player with name '{
playerName
}
'");
return;
}
var kit = FindKitByName(kitName);
if (kit == null) {
SendReply(arg, $"Can't find kit with name '{
kitName
}
'");
return;
}
GiveKit(player, kitName);
SendReply(arg, $"You gave kit {
kitName
}
to {
player.displayName
}
!");
return;
}
if (command == commandConvertConstant && arg.IsAdmin) {
var before = config.kits.Length;
ConvertUmodKits();
var after = config.kits.Length;
SendReply(arg, $"{
after - before
}
was converted!");
return;
}
cmdControlChat(arg.Player(), command, args);
}
private void cmdControlChat(BasePlayer player, string command, string[] args) {
args = args ?? new string[] {
};
var action = args.Length > 0 ? args[0].ToLower() : "true";
var name = args.Length > 1 ? args[1] : "null";
var refreshUI = args.Contains("ui.refresh");
var sendContent = args.Contains("items") || args.Contains("info") || args.Contains("content");
if (sendContent == true) {
SendInfo(player, name);
return;
}
switch (action) {
case "true": SendKits(player);
break;
case "add": case "create": case "new": AddNewKit(player, name);
break;
case "remove": case "delete": case "destroy": case "del": RemoveExistingKit(player, name);
break;
case "update": case "updateitems": UpdateKitItems(player, name);
break;
case "reload": case "load": LoadKits(player);
break;
case "page": var page = 0;
int.TryParse(name, out page);
Interface.CallHook("OpenKitUIPage", player, page);
break;
default: TryToClaimKit(player, action, refreshUI);
break;
}
}
private void TryToClaimKit(BasePlayer player, string name, bool refreshUI) {
if (config.useUi == true && refreshUI == true) {
NextTick(() => {
Interface.CallHook("OnKitUIRefreshRequested", player);
}
);
}
var kit = FindKitByName(name);
if (kit == null) {
SendMessage(player, MessageType.NoKit, "{
name
}
", name);
return;
}
if (config.bypassAllChecksForAdmins == true && player.IsAdmin == true) {
GiveKit(player, kit);
return;
}
if (CanUse(player) == false) {
SendMessage(player, MessageType.CantUse);
return;
}
if (HasPermission(player, kit.permission) == false || kit.forAPI == true) {
SendMessage(player, MessageType.Permission);
return;
}
var kitInfo = GetDataKitInfo(player, kit.name);
if (kit.uses > 0) {
var left = kit.uses - kitInfo.uses;
if (left <= 0) {
SendMessage(player, MessageType.UsesLimitChat, "{
limit
}
", kit.uses);
return;
}
SendMessage(player, MessageType.UsesLeftChat, "{
left
}
", left - 1);
}
if (kit.block > 0 && kit.blockBypass == false) {
var unblockDate = SaveRestore.SaveCreatedTime.AddSeconds(kit.block);
var leftSpan = unblockDate - DateTime.UtcNow;
if (leftSpan.TotalSeconds > 0) {
SendMessage(player, MessageType.WipeblockChat, "{
d
}
", leftSpan.Days, "{
h
}
", leftSpan.Hours, "{
m
}
", leftSpan.Minutes, "{
s
}
", leftSpan.Seconds);
return;
}
else {
kit.blockBypass = true;
}
}
if (kit.cooldown > 0) {
var unblockDate = kitInfo.lastUse.AddSeconds(kit.cooldown);
var leftSpan = unblockDate - DateTime.UtcNow;
if (leftSpan.TotalSeconds > 0) {
SendMessage(player, MessageType.CooldownChat, "{
d
}
", leftSpan.Days, "{
h
}
", leftSpan.Hours, "{
m
}
", leftSpan.Minutes, "{
s
}
", leftSpan.Seconds);
return;
}
}
if (config.checkForFreeSpace == true) {
var need = 0;
var needWear = kit.items.Where(x => x.container.ToLower() == "wear").Count();
var needMain = kit.items.Where(x => x.container.ToLower() == "main").Count();
var needBelt = kit.items.Where(x => x.container.ToLower() == "belt").Count();
var freeWear = player.inventory.containerWear.capacity - player.inventory.containerWear.itemList.Count;
var freeMain = player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count;
var freeBelt = player.inventory.containerBelt.capacity - player.inventory.containerBelt.itemList.Count;
if (needWear > freeWear) {
need += needWear - freeWear;
}
if (needMain > freeMain) {
need += needMain - freeMain;
}
if (needBelt > freeBelt) {
need += needBelt - freeBelt;
}
if (need > 0) {
SendMessage(player, MessageType.NoFreeSpace, "{
amount
}
", need);
return;
}
}
kitInfo.lastUse = DateTime.UtcNow;
kitInfo.uses += 1;
GiveKit(player, kit);
}
private void SendKits(BasePlayer player) {
if (config.useUi == false || Interface.Oxide.CallHook("CanSeeKits", player) == null) {
SendKitsInChat(player);
}
}
private void SendInfo(BasePlayer player, string name) {
if (config.useUi == false || Interface.Oxide.CallHook("CanSeeKitsInfo", player, name) == null) {
SendKitContentText(player, name);
}
}
private void SendKitsInChat(BasePlayer player) {
var kitsString = string.Empty;
foreach (var kit in GetAvailableKits(player)) {
kitsString += GetMessage(MessageType.KitChatEntry, player.UserIDString, "{
name
}
", kit.displayName, "{
description
}
", kit.description, "{
cooldown
}
", kit.cooldown);
}
SendMessage(player, MessageType.KitsListChat, "{
list
}
", kitsString);
}
private void SendKitContentText(BasePlayer player, string name) {
var kit = FindKitByName(name);
if (kit == null) {
SendMessage(player, MessageType.NoKit, "{
name
}
", name);
return;
}
var contentString = string.Empty;
foreach (var item in kit.items) {
contentString += GetMessage(MessageType.ItemChatEntry, player.UserIDString, "{
name
}
", item.shortname, "{
amount
}
", item.amount);
}
SendMessage(player, MessageType.KitsContentChat, "{
name
}
", kit.displayName, "{
list
}
", contentString);
}
private void ConvertUmodKits() {
var obj = Interface.Oxide.DataFileSystem.ReadObject<uModData>("Kits");
var kits = obj.Kits.Values.Select(x => x.ToNormalKit()).ToArray();
config.kits = config.kits.Concat(kits).ToArray();
SaveConfig();
}
private Kit[] GetAvailableKits(BasePlayer player) {
var list = new List<Kit>();
foreach (var kit in config.kits) {
if (config.bypassAllChecksForAdmins == true && player.IsAdmin == true) {
list.Add(kit);
continue;
}
if (kit.forAPI == true) {
continue;
}
if (kit.showWithoutPermission == false && HasPermission(player.UserIDString, kit.permission) == false) {
continue;
}
list.Add(kit);
}
return list.ToArray();
}
private static KitInfo GetDataKitInfo(BasePlayer player, string kitName, DataEntry data = null) {
data = data ?? Data.Get(player.UserIDString, true);
var kitInfo = (KitInfo) null;
if (data.kitsInfo.TryGetValue(kitName, out kitInfo) == false) {
kitInfo = new KitInfo();
data.kitsInfo.Add(kitName, kitInfo);
}
return kitInfo;
}
private void LoadImages() {
var previews = config.kits.Where(x => string.IsNullOrEmpty(x.url) == false).Select(xx => xx.url).ToArray();
var contents = config.kits.SelectMany(x => x.items).Select(x => x.shortname).Distinct().ToArray();
var total = previews.Concat(contents).Distinct().ToArray();
foreach (var url in total) {
if (string.IsNullOrEmpty(url) == true) {
continue;
}
AddImage(url);
}
Puts($"Loaded {
total.Count()
}
images");
}
private void LoadKits(BasePlayer player = null) {
if (player != null && player.IsAdmin == false) {
SendMessage(player, MessageType.Permission);
return;
}
LoadConfig();
Interface.CallHook("OnKitsLoaded");
}
private void UpdateKitItems(BasePlayer player, string name) {
if (player.IsAdmin == false) {
SendMessage(player, MessageType.Permission);
return;
}
LoadConfig();
var kit = FindKitByName(name);
if (kit == null) {
SendMessage(player, MessageType.NoKit, "{
name
}
", name);
return;
}
kit.items = GetPlayerItems(player);
SendMessage(player, $"{
kit.displayName
}
[{
kit.name
}
] items was updated!");
SaveConfig();
}
private void RemoveExistingKit(BasePlayer player, string name) {
if (player.IsAdmin == false) {
SendMessage(player, MessageType.Permission);
return;
}
LoadConfig();
var kit = FindKitByName(name);
if (kit == null) {
SendMessage(player, MessageType.NoKit, "{
name
}
", name);
return;
}
RemoveKit(kit);
SendMessage(player, MessageType.KitRemoved, "{
name
}
", name);
}
private void AddNewKit(BasePlayer player, string name) {
if (player.IsAdmin == false) {
SendMessage(player, MessageType.Permission);
return;
}
LoadConfig();
var kit = new Kit {
name = name, displayName = name, items = GetPlayerItems(player), description = $"Created by {
player.displayName
}
at {
DateTime.UtcNow
}
"
};
AddKit(kit);
SendMessage(player, MessageType.KitAdded, "{
name
}
", name, "{
amount
}
", kit.items.Length);
}
private BaseItem[] GetPlayerItems(BasePlayer player) {
var inventory = player.inventory;
var items = new List<BaseItem>();
foreach (var item in inventory.containerBelt.itemList) {
items.Add(new BaseItem().Create(item, "Belt"));
}
foreach (var item in inventory.containerWear.itemList) {
items.Add(new BaseItem().Create(item, "Wear"));
}
foreach (var item in inventory.containerMain.itemList) {
if (item.position < 24) {
items.Add(new BaseItem().Create(item, "Main"));
}
}
return items.ToArray();
}
private void GiveKit(BasePlayer player, Kit kit) {
if (kit == null) {
return;
}
foreach (var value in kit.items) {
value.GiveTo(player);
}
if (kit.forAPI == false) {
SendMessage(player, MessageType.KitReceived, "{
name
}
", kit.name);
}
Interface.Oxide.CallHook("OnKitRedeemed", player, kit.name);
}
private static Kit FindKitByName(string name) {
return config.kits.FirstOrDefault(x => string.Equals(x.name, name, StringComparison.OrdinalIgnoreCase));
}
private void GiveKit(BasePlayer player, string name) {
GiveKit(player, FindKitByName(name));
}
private void AddKit(Kit kit) {
config.kits = config.kits.Concat(new Kit[]{
kit
}
).ToArray();
SaveConfig();
Interface.CallHook("OnKitAdded", kit.name);
}
private void RemoveKit(Kit kit) {
config.kits = config.kits.Where(x => x != kit).ToArray();
SaveConfig();
Interface.CallHook("OnKitRemoved", kit.name);
}
private bool HasPermission(string userID, string perm) {
return string.IsNullOrEmpty(perm) || permission.UserHasPermission(userID, perm);
}
private bool HasPermission(BasePlayer player, string perm) {
return HasPermission(player.UserIDString, perm);
}
private static BasePlayer FindPlayer(string nameOrID) {
var players = BasePlayer.activePlayerList;
var targets = players.Where(x => x.UserIDString == nameOrID || x.displayName.ToLower().Contains(nameOrID.ToLower())).ToList();
if (targets.Count == 0 || targets.Count > 1) {
return null;
}
return targets[0];
}
private static ConfigData config = new ConfigData();
private class ConfigData {
[JsonProperty(PropertyName = "Command")] public string[] commands = {
"kit", "kits"
};
[JsonProperty(PropertyName = "Check for free space in inventory")] public bool checkForFreeSpace = false;
[JsonProperty(PropertyName = "Use UI plugin if its installed")] public bool useUi = true;
[JsonProperty(PropertyName = "Bypass all checks for admins")] public bool bypassAllChecksForAdmins = false;
[JsonProperty(PropertyName = "[Data] Wipe on new map")] public bool autoWipeData = false;
[JsonProperty(PropertyName = "[Data] Remove values that was not used more than 14 days")] public bool autoCleanData = false;
[JsonProperty(PropertyName = "Kit list")] public Kit[] kits = {
new Kit {
displayName = "Test Kit #1", cooldown = 300, block = 600, description = "Test kit #1", name = "test1", permission = "",
}
, new Kit {
displayName = "Test Kit #2", cooldown = 300, block = 86400 * 5, description = "Test kit #2", name = "test2", permission = "",
}
,
};
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<ConfigData>();
if (config == null) {
LoadDefaultConfig();
}
}
catch {
for (var i = 0;
i < 3;
i++) {
PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
}
LoadDefaultConfig();
return;
}
ValidateConfig();
SaveConfig();
}
private static void ValidateConfig() {
if (ConVar.Server.hostname.Contains("[DEBUG]") == true) {
config = new ConfigData();
}
foreach (var kit in config.kits) {
if (string.IsNullOrEmpty(kit.name)) {
kit.name = "Kit " + Core.Random.Range(0, 99999).ToString();
}
}
}
protected override void LoadDefaultConfig() {
config = new ConfigData();
}
protected override void SaveConfig() {
Config.WriteObject(config);
}
private Dictionary<object, string> langMessages = new Dictionary<object, string> {
{
MessageType.Usage, "Usage:\n"
}
, {
MessageType.Permission, "<color=#ff0000>You don't have permission to use that!</color>"
}
, {
MessageType.CantUse, "You can't use it right now"
}
, {
MessageType.NoKit, "Can't find kit with name '{
name
}
'"
}
, {
MessageType.AvailableUI, "Click to earn"
}
, {
MessageType.PermissionChat, "You don't have permission to use that!"
}
, {
MessageType.PermissionUI, "No Permission"
}
, {
MessageType.CooldownChat, "Cooldown for {
d
}
d {
h
}
h {
m
}
m {
s
}
s !"
}
, {
MessageType.CooldownUI, "Cooldown: {
d
}
d {
h
}
h {
m
}
m {
s
}
s"
}
, {
MessageType.WipeblockChat, "That kit is blocked since wipe. {
d
}
d {
h
}
h {
m
}
m {
s
}
s left"
}
, {
MessageType.WipeblockUI, "Wipe block: {
h
}
h {
m
}
m {
s
}
s"
}
, {
MessageType.UsesLimitChat, "You already used maximal amount of that kit! (Limit: {
limit
}
)"
}
, {
MessageType.UsesLeftChat, "Uses left: {
left
}
"
}
, {
MessageType.UsesLeftUI, "Uses: {
left
}
"
}
, {
MessageType.KitAdded, "You successfully added kit '{
name
}
' with '{
count
}
' items"
}
, {
MessageType.KitRemoved, "You successfully removed kit '{
name
}
'"
}
, {
MessageType.KitReceived, "You successfully get kit!"
}
, {
MessageType.KitsListChat, "Currents kits:\n{
list
}
"
}
, {
MessageType.KitsContentChat, "Kit {
name
}
including:\n{
list
}
"
}
, {
MessageType.KitChatEntry, "<color=#ff0000> {
name
}
</color> - {
description
}
(Cooldown: {
cooldown
}
)\n"
}
, {
MessageType.ItemChatEntry, " {
name
}
x{
amount
}
\n"
}
, {
MessageType.NoFreeSpace, "You dont have free space in your inventory! More {
amount
}
needed!"
}
};
private enum MessageType {
Usage, Permission, CantUse, AvailableUI, NoKit, KitsListChat, KitsContentChat, PermissionChat, PermissionUI, CooldownChat, CooldownUI, WipeblockChat, WipeblockUI, UsesLimitChat, UsesLeftChat, UsesLeftUI, KitAdded, KitRemoved, KitReceived, KitChatEntry, ItemChatEntry, NoFreeSpace,
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(langMessages.ToDictionary(x => x.Key.ToString(), y => y.Value), this);
}
private string GetMessage(MessageType key, string playerID = null, params object[] args) {
var message = lang.GetMessage(key.ToString(), this, playerID);
var dic = OrganizeArgs(args);
if (dic != null) {
foreach (var pair in dic) {
var s0 = "{
" + pair.Key + "
}
";
var s1 = pair.Key;
var s2 = pair.Value != null ? pair.Value.ToString() : "null";
message = message.Replace(s0, s2, StringComparison.InvariantCultureIgnoreCase);
message = message.Replace(s1, s2, StringComparison.InvariantCultureIgnoreCase);
}
}
return message;
}
private void SendMessage(object receiver, string message) {
if (receiver == null) {
Puts(message);
return;
}
var console = receiver as ConsoleSystem.Arg;
if (console != null) {
SendReply(console, message);
return;
}
var player = receiver as BasePlayer;
if (player != null) {
player.ChatMessage(message);
return;
}
}
private void SendMessage(object receiver, MessageType key, params object[] args) {
var userID = (receiver as BasePlayer)?.UserIDString;
var message = GetMessage(key, userID, args);
SendMessage(receiver, message);
}
private static Dictionary<string, object> OrganizeArgs(object[] args) {
var dic = new Dictionary<string, object>();
for (var i = 0;
i < args.Length;
i += 2) {
var value = args[i].ToString();
var nextValue = i + 1 < args.Length ? args[i + 1] : null;
dic.TryAdd(value, nextValue);
}
return dic;
}
private static PluginData Data = new PluginData();
private string dataFilename => $"{
Name
}
\\data";
private bool dataValid = false;
private class DataEntry {
[JsonProperty] private DateTime lastUse = DateTime.UtcNow;
[JsonProperty] private int loadsCount = 0;
[JsonIgnore] public double daysSinceLastUse => (DateTime.UtcNow - lastUse).TotalDays;
[JsonProperty] public Dictionary<string, KitInfo> kitsInfo = new Dictionary<string, KitInfo>();
public void MarkUsed() {
lastUse = DateTime.UtcNow;
loadsCount++;
}
}
private class PluginData {
[JsonProperty] private Dictionary<string, DataEntry> values = new Dictionary<string, DataEntry>();
[JsonProperty] public readonly DateTime creationTime = SaveRestore.SaveCreatedTime;
[JsonIgnore] private Dictionary<string, DataEntry> cache = new Dictionary<string, DataEntry>();
[JsonIgnore] public bool needWipe => config.autoWipeData && SaveRestore.SaveCreatedTime > creationTime && differentCreationDates;
[JsonIgnore] public bool needCleanup => config.autoCleanData && values.Count > minimalLimitForCleanup;
[JsonIgnore] private bool differentCreationDates => (SaveRestore.SaveCreatedTime - creationTime).TotalHours > 1;
[JsonIgnore] private static int cacheLifeSpan => 300;
[JsonIgnore] public static int unusedDataLifeSpanDays => 14;
[JsonIgnore] private static int minimalLimitForCleanup => 500;
[JsonIgnore] public int valuesCount => values.Count;
public DataEntry Get(object param, bool createNewOnMissing) {
var key = GetKeyFrom(param);
if (string.IsNullOrEmpty(key) == true) {
return null;
}
var value = (DataEntry) null;
if (cacheLifeSpan > 0 && cache.TryGetValue(key, out value) == true) {
return value;
}
if (values.TryGetValue(key, out value) == false && createNewOnMissing == true) {
value = new DataEntry();
values.Add(key, value);
}
if (value != null) {
value.MarkUsed();
if (cacheLifeSpan > 0) {
cache.TryAdd(key, value);
}
}
return value;
}
public void Set(object param, DataEntry value) {
var key = GetKeyFrom(param);
if (string.IsNullOrEmpty(key) == true) {
return;
}
if (value == null) {
if (values.ContainsKey(key) == true) {
values.Remove(key);
}
if (cache.ContainsKey(key) == true) {
cache.Remove(key);
}
}
else {
if (values.TryAdd(key, value) == false) {
values[key] = value;
if (cache.ContainsKey(key) == true) {
cache[key] = value;
}
}
}
}
public void Cleanup() {
var keys = new List<string>();
foreach (var pair in values) {
var key = pair.Key;
var value = pair.Value;
if (value.daysSinceLastUse > unusedDataLifeSpanDays) {
keys.Add(key);
}
}
foreach (var key in keys) {
Set(key, null);
}
}
public void ResetCache() {
cache.Clear();
}
private static string GetKeyFrom(object obj) {
if (obj == null) {
return null;
}
if (obj is string) {
return obj as string;
}
if (obj is BasePlayer) {
return (obj as BasePlayer).UserIDString;
}
if (obj is BaseNetworkable) {
return (obj as BaseNetworkable).net?.ID.ToString();
}
return obj.ToString();
}
}
private void LoadData() {
try {
Data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{
dataFilename
}
");
if (Data.needWipe == true) {
Interface.Oxide.DataFileSystem.WriteObject($"{
dataFilename
}
_old", Data);
Data = new PluginData();
PrintWarning($"Data was wiped by auto-wiping function (Old: {
Data.creationTime
}
, New: {
SaveRestore.SaveCreatedTime
}
)");
}
if (Data.needCleanup == true) {
var oldCount = Data.valuesCount;
Data.Cleanup();
var newCount = Data.valuesCount;
PrintWarning($"Removed {
oldCount - newCount
}
values that are older than {
PluginData.unusedDataLifeSpanDays
}
days (Was: {
oldCount
}
, Now: {
newCount
}
)");
}
dataValid = true;
timer.Every(Core.Random.Range(500, 700), SaveData);
SaveData();
}
catch (Exception e) {
Data = new PluginData();
dataValid = false;
for (var i = 0;
i < 5;
i++) {
PrintError("!!! CRITICAL DATA ERROR !!!\n * Data was not loaded!\n * Data auto-save was disabled!");
}
LogToFile("errors", $"\n\nError: {
e.Message
}
\n\nTrace: {
e.StackTrace
}
\n\n", this);
}
}
private void SaveData() {
if (Data != null && dataValid == true) {
Data.ResetCache();
Interface.Oxide.DataFileSystem.WriteObject(dataFilename, Data);
}
}
private class BaseItem {
[JsonProperty(PropertyName = "Command")] public string command = string.Empty;
[JsonProperty(PropertyName = "Shortname")] public string shortname = string.Empty;
[JsonProperty(PropertyName = "Amount")] public int amount = 1;
[JsonProperty(PropertyName = "Skin")] public ulong skinId;
[JsonProperty(PropertyName = "Random skin")] public bool randomizeSkin = false;
[JsonProperty(PropertyName = "Display name")] public string displayName;
[JsonProperty(PropertyName = "Blueprint")] public bool isBlueprint;
[JsonProperty(PropertyName = "Container")] public string container = string.Empty;
[JsonProperty(PropertyName = "Slot")] public int slot;
[JsonProperty(PropertyName = "Fuel")] public float fuel;
[JsonProperty(PropertyName = "Contents")] public Dictionary<string, int> contents = new Dictionary<string, int>();
[JsonProperty(PropertyName = "Condition (don't change me)")] public float condition;
[JsonProperty(PropertyName = "Maximal Condition (don't change me)")] public float maxCondition;
public void GiveTo(BasePlayer player) {
if (player == null) {
return;
}
var item = Create();
if (item != null) {
var container = (ItemContainer) null;
switch (this.container.ToLower()) {
case "belt": container = player.inventory.containerBelt;
break;
case "main": container = player.inventory.containerMain;
break;
case "wear": container = player.inventory.containerWear;
break;
}
if (container == null || item.MoveToContainer(container, slot) == false) {
player.GiveItem(item);
}
}
if (string.IsNullOrEmpty(command) == false) {
RunCommand(player);
}
}
public void GiveTo(string playerID) {
var player = BasePlayer.Find(playerID) ?? BasePlayer.FindSleeping(playerID);
if (player == null) {
RunCommand(playerID);
}
else {
GiveTo(player);
}
}
private Item Create() {
if (isBlueprint) {
var blueprint = ItemManager.CreateByName("blueprintbase", amount);
blueprint.blueprintTarget = ItemManager.FindItemDefinition(shortname).itemid;
return blueprint;
}
var item = ItemManager.CreateByName(shortname, amount, skinId);
if (item == null) {
return null;
}
if (randomizeSkin == true) {
Interface.CallHook("SetRandomSkin", null, item);
}
item.name = displayName;
if (maxCondition > 0) {
item.maxCondition = maxCondition;
item.condition = condition;
}
item.fuel = fuel;
var weapon = item?.GetHeldEntity()?.GetComponent<BaseProjectile>();
foreach (var defC in contents) {
var name = defC.Key;
var amount = defC.Value;
if ((name.StartsWith("arrow.") || name.StartsWith("ammo.")) && weapon != null) {
weapon.primaryMagazine.ammoType = ItemManager.FindItemDefinition(name);
weapon.primaryMagazine.contents = amount;
continue;
}
var content = ItemManager.CreateByName(name, amount);
content?.MoveToContainer(item.contents);
}
weapon?.SendNetworkUpdateImmediate();
return item;
}
public BaseItem Create(Item item, string rootContainer = null) {
var value = new BaseItem {
shortname = item.blueprintTarget != 0 ? ItemManager.FindItemDefinition(item.blueprintTarget).shortname : item.info.shortname, amount = item.amount, skinId = item.skin, displayName = item.name, condition = item.condition, maxCondition = item.maxCondition, fuel = item.fuel, isBlueprint = item.blueprintTarget != 0, slot = item.position, container = rootContainer,
};
foreach (var subItem in item.contents?.itemList ?? new List<Item>()) {
value.contents.Add(subItem.info.shortname, subItem.amount);
}
var weapon = item.GetHeldEntity()?.GetComponent<BaseProjectile>()?.primaryMagazine;
if (weapon != null) {
value.contents.Add(weapon.ammoType.shortname, weapon.contents);
}
return value;
}
private void RunCommand(BasePlayer player) {
RunCommand(player.UserIDString);
}
private void RunCommand(string playerID) {
if (string.IsNullOrEmpty(command)) {
return;
}
var cmd = command .Replace("{
userid
}
", playerID, StringComparison.OrdinalIgnoreCase) .Replace("{
playerid
}
", playerID, StringComparison.OrdinalIgnoreCase);
ConsoleSystem.Run(ConsoleSystem.Option.Server, cmd);
}
}
private class Kit {
[JsonProperty(PropertyName = "Shortname", Order = 1)] public string name = string.Empty;
[JsonProperty(PropertyName = "Display name", Order = 2)] public string displayName = string.Empty;
[JsonProperty(PropertyName = "Permission", Order = 3)] public string permission = "kits.new";
[JsonProperty(PropertyName = "Cooldown", Order = 4)] public int cooldown = 3600;
[JsonProperty(PropertyName = "Wipe-block time", Order = 5)] public int block = 0;
[JsonProperty(PropertyName = "Icon", Order = 6)] public string url = string.Empty;
[JsonProperty(PropertyName = "Description", Order = 7)] public string description = string.Empty;
[JsonProperty(PropertyName = "Max uses", Order = 8)] public int uses = 0;
[JsonProperty(PropertyName = "API Kit", Order = 800)] public bool forAPI = false;
[JsonProperty(PropertyName = "Show without uses", Order = 801)] public bool showWithoutUses = false;
[JsonProperty(PropertyName = "Show without permission", Order = 802)] public bool showWithoutPermission = false;
[JsonProperty(PropertyName = "Show if wipe-blocked", Order = 803)] public bool showIfWipeBlocked = true;
[JsonProperty(PropertyName = "Show if on cooldown", Order = 804)] public bool showIfOnCooldown = true;
[JsonProperty(PropertyName = "Custom message if doesn't have permission", Order = 900)] public string messageForNoPermission = string.Empty;
[JsonProperty(PropertyName = "Items", Order = 999)] public BaseItem[] items = {
new BaseItem {
shortname = "stonehatchet"
}
, new BaseItem {
shortname = "pickaxe"
}
};
[JsonIgnore] public bool blockBypass = false;
}
private class uModData {
public Dictionary<string, uModKit> Kits = new Dictionary<string, uModKit>();
}
private class uModKit {
public string name;
public string description;
public int max;
public double cooldown;
public int authlevel;
public bool hide;
public bool npconly;
public string permission;
public string image;
public string building;
public List<uModKitItem> items = new List<uModKitItem>();
public Kit ToNormalKit() {
return new Kit {
name = name, description = description, uses = max, cooldown = Convert.ToInt32(cooldown), forAPI = hide || npconly, permission = permission, url = image, items = items.Select(x => x.ToBaseItem()).ToArray()
};
}
}
private class uModKitItem {
public int itemid;
public string container;
public int amount;
public ulong skinid;
public bool weapon;
public int blueprintTarget;
public List<int> mods = new List<int>();
public BaseItem ToBaseItem() {
return new BaseItem {
shortname = ItemManager.FindItemDefinition(itemid)?.shortname, container = container, amount = amount, skinId = skinid, isBlueprint = blueprintTarget != 0, contents = mods.ToDictionary(x => ItemManager.FindItemDefinition(x)?.shortname, y => 1)
};
}
}
[PluginReference] private Plugin ImageLibrary;
private void AddImage(string url) {
if (ImageLibrary == null) {
return;
}
if (string.IsNullOrWhiteSpace(url) == true) {
return;
}
if (url.StartsWith("http") == false && url.StartsWith("www") == false) {
url = $"https://rustlabs.com/img/items180/{
url
}
.png";
}
var obj = ImageLibrary.Call("HasImage", url, (ulong) 0);
if (obj != null && (bool) obj == false) {
ImageLibrary.CallHook("AddImage", url, url, (ulong) 0);
}
}
private string GetImage(string url) {
var obj = ImageLibrary?.Call("GetImage", url);
return obj?.ToString();
}
private static bool CanUse(BasePlayer player) {
return Interface.Oxide.CallHook("canRedeemKit", player) == null && Interface.Oxide.CallHook("CanUseKit", player) == null;
}
private bool isKit(string kitname) {
return FindKitByName(kitname) != null;
}
private string[] GetKitContents(string kitname, bool random = false) {
var kit = FindKitByName(kitname);
if (kit == null) {
return null;
}
var items = new List<string>();
foreach (var item in kit.items) {
var itemString = $"{
ItemManager.FindItemDefinition(item.shortname)?.itemid
}
_{
item.amount
}
";
if (item.contents.Count > 0) foreach (var mod in item.contents) {
itemString += $"_{
mod
}
";
}
items.Add(itemString);
}
return items.Count > 0 ? items.ToArray() : null;
}
private object GetKitInfo(string kitname) {
var kit = FindKitByName(kitname);
if (kit == null) {
return null;
}
var obj = new JObject {
["name"] = kit.name, ["permission"] = kit.permission, ["npconly"] = kit.forAPI, ["max"] = kit.uses, ["image"] = kit.url, ["hide"] = kit.forAPI, ["description"] = kit.description, ["cooldown"] = kit.cooldown, ["building"] = false, ["authlevel"] = 0
};
var items = new JArray();
foreach (var itemEntry in kit.items) {
var item = new JObject();
item["amount"] = itemEntry.amount;
item["container"] = itemEntry.container;
item["itemid"] = ItemManager.FindItemDefinition(itemEntry.shortname)?.itemid;
item["skinid"] = itemEntry.skinId;
item["weapon"] = ItemManager.FindItemDefinition(itemEntry.shortname)?.GetComponent<HeldEntity>() != null;
item["blueprint"] = itemEntry.isBlueprint;
item["mods"] = null;
items.Add(item);
}
obj["items"] = items;
return obj;
}
private string API_GetPlayerUIKits(BasePlayer player) {
return GetPlayerKitsForUI(player);
}
private string API_GetKitForUI(BasePlayer player, string kit) {
return GetKitForUI(player, kit);
}
private string[] GetAllKits() {
return config.kits.Select(x => x.name).Where(x => string.IsNullOrEmpty(x) == false).ToArray();
}
private string GetPlayerKitsForUI(BasePlayer player) {
var kits = config.kits.Where(x => x.forAPI == false);
var list = new List<KitUI>();
var data = Data.Get(player.UserIDString, true);
foreach (var kit in kits) {
var kitInfo = GetDataKitInfo(player, kit.name, data);
var message = GetUIMessage(player, kit, kitInfo);
if (message == null) {
continue;
}
var obj = new KitUI {
block = kit.block, cooldown = kit.cooldown, description = kit.description, name = kit.name, items = new Dictionary<string, int>(), url = kit.url, uses = kit.uses, displayName = kit.displayName, messageOnButton = message
};
foreach (var item in kit.items) {
if (obj.items.TryAdd(item.shortname, item.amount) == false) {
obj.items[item.shortname] += item.amount;
}
}
list.Add(obj);
}
var array = list.ToArray();
return JsonConvert.SerializeObject(array);
}
private string GetKitForUI(BasePlayer player, string name) {
var kit = FindKitByName(name);
if (kit == null) {
return null;
}
var data = GetDataKitInfo(player, name);
var obj = new KitUI {
block = kit.block, cooldown = kit.cooldown, uses = kit.uses - data.uses, displayName = kit.displayName, description = kit.description, items = new Dictionary<string, int>(),
};
foreach (var item in kit.items) {
if (obj.items.ContainsKey(item.shortname)) {
obj.items[item.shortname] += item.amount;
}
else {
obj.items.Add(item.shortname, item.amount);
}
}
return JsonConvert.SerializeObject(obj);
}
private string GetUIMessage(BasePlayer player, Kit kit, KitInfo kitInfo) {
if (HasPermission(player, kit.permission) == false) {
if (kit.showWithoutPermission == false) {
return null;
}
return string.IsNullOrEmpty(kit.messageForNoPermission) ? GetMessage(MessageType.PermissionUI, player.UserIDString) : kit.messageForNoPermission;
}
if (kit.uses > 0) {
var left = kit.uses - kitInfo.uses;
if (left <= 0) {
return kit.showWithoutUses == false ? null : GetMessage(MessageType.UsesLeftUI, "{
limit
}
", 0);
}
}
if (kit.block > 0 && kit.blockBypass == false) {
var unblockDate = SaveRestore.SaveCreatedTime.AddSeconds(kit.block);
var leftSpan = unblockDate - DateTime.UtcNow;
if (leftSpan.TotalSeconds > 0) {
return kit.showIfWipeBlocked == false ? null : GetMessage(MessageType.WipeblockUI, player.UserIDString, "{
d
}
", leftSpan.Days, "{
h
}
", leftSpan.Hours, "{
m
}
", leftSpan.Minutes, "{
s
}
", leftSpan.Seconds);
}
else {
kit.blockBypass = true;
}
}
if (kit.cooldown > 0) {
var unblockDate = kitInfo.lastUse.AddSeconds(kit.cooldown);
var leftSpan = unblockDate - DateTime.UtcNow;
if (leftSpan.TotalSeconds > 0) {
return kit.showIfOnCooldown == false ? null : GetMessage(MessageType.CooldownUI, player.UserIDString, "{
d
}
", leftSpan.Days, "{
h
}
", leftSpan.Hours, "{
m
}
", leftSpan.Minutes, "{
s
}
", leftSpan.Seconds);
}
}
return GetMessage(MessageType.AvailableUI, player.UserIDString);
}
private class KitUI {
public string name = string.Empty;
public string displayName = string.Empty;
public int cooldown = 3600;
public int block = 0;
public string url = string.Empty;
public string description = string.Empty;
public int uses = 0;
public string messageOnButton;
public Dictionary<string, int> items = new Dictionary<string, int>();
}
}
}
© 2020 Quttera Ltd. All rights reserved.