C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Random = UnityEngine.Random;
using Time = UnityEngine.Time;
namespace Oxide.Plugins
{
[Info("Cases", "Sempai#3239", "1.1.1")]
public class Cases : RustPlugin
{
#region Fields
[PluginReference] private Plugin
ImageLibrary = null,
PlaytimeTracker = null,
UINotify = null,
Notify = null;
private const string Layer = "UI.Cases";
private const string ModalLayer = "UI.Cases.Modal";
private static Cases _instance;
private const BindingFlags bindingFlags = BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public;
private const string PERM_EDIT = "Cases.edit";
private readonly Dictionary<int, CaseInfo> _casesByIDs = new Dictionary<int, CaseInfo>();
private readonly Dictionary<string, List<KeyValuePair<int, string>>> _itemsCategories =
new Dictionary<string, List<KeyValuePair<int, string>>>();
private readonly Dictionary<BasePlayer, PlayerItemsData> _playersItems =
new Dictionary<BasePlayer, PlayerItemsData>();
private class PlayerItemsData
{
public readonly int CaseId;
public readonly List<ItemInfo> Items;
public PlayerItemsData(int caseId, List<ItemInfo> items)
{
CaseId = caseId;
Items = items;
}
}
private readonly Dictionary<int, ItemInfo> _itemByIDs = new Dictionary<int, ItemInfo>();
private readonly Dictionary<BasePlayer, float> TimePlayers = new Dictionary<BasePlayer, float>();
#endregion
#region Config
private Configuration _config;
private class Configuration
{
[JsonProperty(PropertyName = "Enable item scrolling?")]
public readonly bool Scrolling = true;
[JsonProperty(PropertyName = "Work with Notify?")]
public readonly bool UseNotify = true;
[JsonProperty(PropertyName = "Permission (ex: cases.use)")]
public string Permission = string.Empty;
[JsonProperty(PropertyName = "Amount of items in the roulette")]
public readonly int AmountItems = 26;
[JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly string[] Commands = {"cases", "opencase"};
[JsonProperty(PropertyName = "Economy")]
public EconomyConf Economy = new EconomyConf
{
Type = EconomyType.Plugin,
AddHook = "Deposit",
BalanceHook = "Balance",
RemoveHook = "Withdraw",
Plug = "Economics",
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0,
Show = true
};
[JsonProperty(PropertyName = "Rarity Colors (chance - color)",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<float, IColor> Rarity = new Dictionary<float, IColor>
{
[70] = new IColor("#AFAFAF", 75),
[65] = new IColor("#6496E1", 75),
[55] = new IColor("#4B69CD", 75),
[50] = new IColor("#8847FF", 75),
[45] = new IColor("#8847FF", 75),
[40] = new IColor("#8847FF", 75),
[35] = new IColor("#8847FF", 75),
[30] = new IColor("#8847FF", 75),
[25] = new IColor("#8847FF", 75),
[20] = new IColor("#D32CE6", 75),
[15] = new IColor("#D32CE6", 75),
[10] = new IColor("#D32CE6", 75),
[5] = new IColor("#EB4B4B", 75)
};
[JsonProperty(PropertyName = "Playtime Tracker Settings")]
public PlaytimeTrackerSettings PlaytimeTrackerConf = new PlaytimeTrackerSettings
{
Enabled = true,
Cases = new Dictionary<int, int>
{
[3600] = 1,
[14400] = 2,
[28800] = 3,
[86400] = 4
}
};
[JsonProperty(PropertyName = "Cases for time settings")]
public TimeCasesSettings TimeCasesSettings = new TimeCasesSettings
{
Enable = false,
Cooldown = 14400,
Cases = new List<int>
{
1,
2,
3,
4,
5
}
};
[JsonProperty(PropertyName = "Bonus Case")]
public BonusCaseInfo BonusCaseInfo = new BonusCaseInfo
{
Enabled = true,
ID = -1,
Title = "Bonus Case",
Image = "https://i.imgur.com/n4I3vI0.png",
Permission = string.Empty,
CooldownTime = 86400,
Cost = 0,
CustomCurrency = new CustomCurrency
{
Enabled = false,
CostFormat = "{0} scrap",
Type = EconomyType.Item,
Plug = string.Empty,
AddHook = string.Empty,
RemoveHook = string.Empty,
BalanceHook = string.Empty,
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
},
Items = new List<ItemInfo>
{
new ItemInfo
{
Type = ItemType.Item,
ID = 1,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "wood",
Skin = 0,
Amount = 3500,
Chance = 70
},
new ItemInfo
{
Type = ItemType.Item,
ID = 2,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "stones",
Skin = 0,
Amount = 2500,
Chance = 70
},
new ItemInfo
{
Type = ItemType.Item,
ID = 3,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "leather",
Skin = 0,
Amount = 1000,
Chance = 55
},
new ItemInfo
{
Type = ItemType.Item,
ID = 4,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "cloth",
Skin = 0,
Amount = 1000,
Chance = 55
},
new ItemInfo
{
Type = ItemType.Item,
ID = 5,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "lowgradefuel",
Skin = 0,
Amount = 500,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 6,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metal.fragments",
Skin = 0,
Amount = 1500,
Chance = 65
},
new ItemInfo
{
Type = ItemType.Item,
ID = 7,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metal.refined",
Skin = 0,
Amount = 150,
Chance = 65
},
new ItemInfo
{
Type = ItemType.Item,
ID = 8,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "sulfur",
Skin = 0,
Amount = 2500,
Chance = 55
},
new ItemInfo
{
Type = ItemType.Item,
ID = 9,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "gunpowder",
Skin = 0,
Amount = 1500,
Chance = 45
},
new ItemInfo
{
Type = ItemType.Item,
ID = 10,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "explosive.timed",
Skin = 0,
Amount = 1,
Chance = 5
}
}
};
[JsonProperty(PropertyName = "Cases", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<CaseInfo> Cases = new List<CaseInfo>
{
new CaseInfo
{
ID = 1,
Title = "ALTAIR",
Image = "https://i.imgur.com/0p9qwot.png",
Permission = string.Empty,
Cost = 100,
CustomCurrency = new CustomCurrency
{
Enabled = false,
CostFormat = "{0} scrap",
Type = EconomyType.Item,
Plug = string.Empty,
AddHook = string.Empty,
RemoveHook = string.Empty,
BalanceHook = string.Empty,
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
},
Items = new List<ItemInfo>
{
new ItemInfo
{
Type = ItemType.Item,
ID = 11,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metalblade",
Skin = 0,
Amount = 40,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 12,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "sewingkit",
Skin = 0,
Amount = 30,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 14,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "roadsigns",
Skin = 0,
Amount = 15,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 15,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metalpipe",
Skin = 0,
Amount = 20,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 16,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "gears",
Skin = 0,
Amount = 15,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 17,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "smgbody",
Skin = 0,
Amount = 5,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 18,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "smgbody",
Skin = 0,
Amount = 5,
Chance = 20
},
new ItemInfo
{
Type = ItemType.Item,
ID = 19,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metalspring",
Skin = 0,
Amount = 20,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 20,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "semibody",
Skin = 0,
Amount = 3,
Chance = 15
},
new ItemInfo
{
Type = ItemType.Item,
ID = 21,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "techparts",
Skin = 0,
Amount = 10,
Chance = 25
},
new ItemInfo
{
Type = ItemType.Item,
ID = 22,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "riflebody",
Skin = 0,
Amount = 10,
Chance = 5
}
}
},
new CaseInfo
{
ID = 2,
Title = "SCHEDAR",
Image = "https://i.imgur.com/rADqKVZ.png",
Permission = string.Empty,
Cost = 150,
CustomCurrency = new CustomCurrency
{
Enabled = false,
CostFormat = "{0} scrap",
Type = EconomyType.Item,
Plug = string.Empty,
AddHook = string.Empty,
RemoveHook = string.Empty,
BalanceHook = string.Empty,
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
},
Items = new List<ItemInfo>
{
new ItemInfo
{
Type = ItemType.Item,
ID = 43,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "scrap",
Skin = 0,
Amount = 500,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 44,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "gunpowder",
Skin = 0,
Amount = 3500,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 45,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.ak",
Skin = 0,
Amount = 1,
Chance = 15
},
new ItemInfo
{
Type = ItemType.Item,
ID = 46,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.semiauto",
Skin = 0,
Amount = 1,
Chance = 20
},
new ItemInfo
{
Type = ItemType.Item,
ID = 47,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "explosive.timed",
Skin = 0,
Amount = 5,
Chance = 20
},
new ItemInfo
{
Type = ItemType.Item,
ID = 48,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "sulfur",
Skin = 0,
Amount = 5000,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 49,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metal.refined",
Skin = 0,
Amount = 300,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 50,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "stones",
Skin = 0,
Amount = 8000,
Chance = 60
},
new ItemInfo
{
Type = ItemType.Item,
ID = 51,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "wood",
Skin = 0,
Amount = 8000,
Chance = 60
},
new ItemInfo
{
Type = ItemType.Item,
ID = 52,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "lmg.m249",
Skin = 0,
Amount = 1,
Chance = 5
},
new ItemInfo
{
Type = ItemType.Item,
ID = 53,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "ammo.rocket.basic",
Skin = 0,
Amount = 4,
Chance = 50
}
}
},
new CaseInfo
{
ID = 3,
Title = "COR CAROLI",
Image = "https://i.imgur.com/ojg7Sn5.png",
Permission = string.Empty,
Cost = 200,
CustomCurrency = new CustomCurrency
{
Enabled = false,
CostFormat = "{0} scrap",
Type = EconomyType.Item,
Plug = string.Empty,
AddHook = string.Empty,
RemoveHook = string.Empty,
BalanceHook = string.Empty,
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
},
Items = new List<ItemInfo>
{
new ItemInfo
{
Type = ItemType.Item,
ID = 23,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "pistol.semiauto",
Skin = 0,
Amount = 1,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 24,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "pistol.python",
Skin = 0,
Amount = 1,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 25,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "pistol.m92",
Skin = 0,
Amount = 1,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 26,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "smg.2",
Skin = 0,
Amount = 1,
Chance = 40
},
new ItemInfo
{
Type = ItemType.Item,
ID = 27,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.m39",
Skin = 0,
Amount = 1,
Chance = 20
},
new ItemInfo
{
Type = ItemType.Item,
ID = 28,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "smg.thompson",
Skin = 0,
Amount = 1,
Chance = 40
},
new ItemInfo
{
Type = ItemType.Item,
ID = 29,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.semiauto",
Skin = 0,
Amount = 1,
Chance = 20
},
new ItemInfo
{
Type = ItemType.Item,
ID = 30,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.lr300",
Skin = 0,
Amount = 1,
Chance = 15
},
new ItemInfo
{
Type = ItemType.Item,
ID = 31,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.bolt",
Skin = 0,
Amount = 1,
Chance = 15
},
new ItemInfo
{
Type = ItemType.Item,
ID = 54,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.ak",
Skin = 0,
Amount = 1,
Chance = 15
}
}
},
new CaseInfo
{
ID = 4,
Title = "PROCYON",
Image = "https://i.imgur.com/1ZttHs8.png",
Permission = string.Empty,
Cost = 200,
CustomCurrency = new CustomCurrency
{
Enabled = false,
CostFormat = "{0} scrap",
Type = EconomyType.Item,
Plug = string.Empty,
AddHook = string.Empty,
RemoveHook = string.Empty,
BalanceHook = string.Empty,
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
},
Items = new List<ItemInfo>
{
new ItemInfo
{
Type = ItemType.Item,
ID = 32,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "explosive.timed",
Skin = 0,
Amount = 5,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 33,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "ammo.rocket.basic",
Skin = 0,
Amount = 8,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 34,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "lmg.m249",
Skin = 0,
Amount = 1,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 35,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "gunpowder",
Skin = 0,
Amount = 8000,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 36,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "rifle.l96",
Skin = 0,
Amount = 1,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 37,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "supply.signal",
Skin = 0,
Amount = 6,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 38,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "explosive.satchel",
Skin = 0,
Amount = 6,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 39,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "ammo.rifle.explosive",
Skin = 0,
Amount = 250,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 40,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "grenade.f1",
Skin = 0,
Amount = 5,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 41,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "workbench3",
Skin = 0,
Amount = 1,
Chance = 60
},
new ItemInfo
{
Type = ItemType.Item,
ID = 42,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "scrap",
Skin = 0,
Amount = 1000,
Chance = 50
}
}
},
new CaseInfo
{
ID = 5,
Title = "SADAMELIK",
Image = "https://i.imgur.com/wIPGCGM.png",
Permission = string.Empty,
Cost = 500,
CustomCurrency = new CustomCurrency
{
Enabled = false,
CostFormat = "{0} scrap",
Type = EconomyType.Item,
Plug = string.Empty,
AddHook = string.Empty,
RemoveHook = string.Empty,
BalanceHook = string.Empty,
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
},
Items = new List<ItemInfo>
{
new ItemInfo
{
Type = ItemType.Item,
ID = 55,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "wood",
Skin = 0,
Amount = 20000,
Chance = 70
},
new ItemInfo
{
Type = ItemType.Item,
ID = 56,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "stones",
Skin = 0,
Amount = 15000,
Chance = 70
},
new ItemInfo
{
Type = ItemType.Item,
ID = 57,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "leather",
Skin = 0,
Amount = 2400,
Chance = 55
},
new ItemInfo
{
Type = ItemType.Item,
ID = 58,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "cloth",
Skin = 0,
Amount = 2300,
Chance = 55
},
new ItemInfo
{
Type = ItemType.Item,
ID = 59,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "lowgradefuel",
Skin = 0,
Amount = 1500,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 60,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "roadsigns",
Skin = 0,
Amount = 35,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 61,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "metalpipe",
Skin = 0,
Amount = 40,
Chance = 50
},
new ItemInfo
{
Type = ItemType.Item,
ID = 62,
Image = string.Empty,
Title = string.Empty,
Command = string.Empty,
Plugin = new PluginItem(),
DisplayName = string.Empty,
ShortName = "gears",
Skin = 0,
Amount = 30,
Chance = 50
}
}
}
};
[JsonProperty(PropertyName = "Wipe Settings")]
public WipeSettings Wipe = new WipeSettings
{
Players = false,
Cooldowns = true
};
[JsonProperty(PropertyName = "UI Settings")]
public InterfaceSettings UI = new InterfaceSettings
{
Colors = new InterfaceSettings.ColorsSettings
{
Color1 = new IColor("#0E0E10", 100),
Color2 = new IColor("#161617", 100),
Color3 = new IColor("#FFFFFF", 100),
Color4 = new IColor("#4B68FF", 100),
Color5 = new IColor("#BFBFBF", 100),
Color6 = new IColor("#4B68FF", 33),
Color7 = new IColor("##324192", 100),
Color8 = new IColor("#FFFFFF", 50),
Color9 = new IColor("#161617", 99),
Color10 = new IColor("#161617", 85),
Color11 = new IColor("#FF4B4B", 100),
Color12 = new IColor("#CD3838", 100),
Color13 = new IColor("#50965F", 100)
}
};
[JsonProperty(PropertyName = "Logs Settings")]
public LogSettings Logs = new LogSettings
{
Console = false,
File = false,
Discord = new LogSettings.DiscordLogs
{
Enabled = false,
WebhookURL =
"Insert webhook here (tutorial: https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks)"
}
};
}
private class LogSettings
{
[JsonProperty(PropertyName = "Enable logging to the console?")]
public bool Console;
[JsonProperty(PropertyName = "Enable logging to the file?")]
public bool File;
[JsonProperty(PropertyName = "Discord Logging")]
public DiscordLogs Discord;
public void Log(string msg)
{
if (string.IsNullOrWhiteSpace(msg))
return;
if (Console)
LogToConsole(msg);
if (File)
LogToFile(msg);
if (Discord?.Enabled == true)
LogToDiscord(msg);
}
private void LogToConsole(string msg)
{
_instance.Puts($"{msg}");
}
private void LogToFile(string msg)
{
_instance.LogToFile("", $"[{DateTime.Now}] {msg}", _instance);
}
private void LogToDiscord(string msg)
{
_instance.DiscordSendMessage(msg, Discord.WebhookURL);
}
public class DiscordLogs
{
[JsonProperty(PropertyName = "Enabled?")]
public bool Enabled;
[JsonProperty(PropertyName = "Webhook URL")]
public string WebhookURL = "";
}
}
private class InterfaceSettings
{
[JsonProperty(PropertyName = "Colors")]
public ColorsSettings Colors;
public class ColorsSettings
{
[JsonProperty(PropertyName = "Color 1")]
public IColor Color1;
[JsonProperty(PropertyName = "Color 2")]
public IColor Color2;
[JsonProperty(PropertyName = "Color 3")]
public IColor Color3;
[JsonProperty(PropertyName = "Color 4")]
public IColor Color4;
[JsonProperty(PropertyName = "Color 5")]
public IColor Color5;
[JsonProperty(PropertyName = "Color 6")]
public IColor Color6;
[JsonProperty(PropertyName = "Color 7")]
public IColor Color7;
[JsonProperty(PropertyName = "Color 8")]
public IColor Color8;
[JsonProperty(PropertyName = "Color 9")]
public IColor Color9;
[JsonProperty(PropertyName = "Color 10")]
public IColor Color10;
[JsonProperty(PropertyName = "Color 11")]
public IColor Color11;
[JsonProperty(PropertyName = "Color 12")]
public IColor Color12;
[JsonProperty(PropertyName = "Color 13")]
public IColor Color13;
}
}
private class WipeSettings
{
[JsonProperty(PropertyName = "Wipe Players?")]
public bool Players;
[JsonProperty(PropertyName = "Wipe Cooldowns?")]
public bool Cooldowns;
}
private class TimeCasesSettings
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enable;
[JsonProperty(PropertyName = "Cooldown (seconds)")]
public float Cooldown;
[JsonProperty(PropertyName = "Cases (IDs)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<int> Cases;
}
private class PlaytimeTrackerSettings
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Playtime (seconds) - CaseID",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<int, int> Cases;
}
private class IColor
{
[JsonProperty(PropertyName = "HEX")] public string HEX;
[JsonProperty(PropertyName = "Opacity (0 - 100)")]
public readonly float Alpha;
public string Get()
{
if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";
var str = HEX.Trim('#');
if (str.Length != 6) throw new Exception(HEX);
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
}
public IColor(string hex, float alpha)
{
HEX = hex;
Alpha = alpha;
}
}
private enum EconomyType
{
Plugin,
Item
}
private abstract class EconomyTemplate
{
[JsonProperty(PropertyName = "Type (Plugin/Item)")] [JsonConverter(typeof(StringEnumConverter))]
public EconomyType Type;
[JsonProperty(PropertyName = "Plugin name")]
public string Plug;
[JsonProperty(PropertyName = "Balance add hook")]
public string AddHook;
[JsonProperty(PropertyName = "Balance remove hook")]
public string RemoveHook;
[JsonProperty(PropertyName = "Balance show hook")]
public string BalanceHook;
[JsonProperty(PropertyName = "ShortName")]
public string ShortName;
[JsonProperty(PropertyName = "Display Name (empty - default)")]
public string DisplayName;
[JsonProperty(PropertyName = "Skin")] public ulong Skin;
public double ShowBalance(BasePlayer player)
{
switch (Type)
{
case EconomyType.Plugin:
{
var plugin = _instance?.plugins?.Find(Plug);
if (plugin == null) return 0;
return Math.Round(Convert.ToDouble(plugin.Call(BalanceHook, player.userID)));
}
case EconomyType.Item:
{
return ItemCount(player.inventory.AllItems(), ShortName, Skin);
}
default:
return 0;
}
}
public void AddBalance(BasePlayer player, double amount)
{
switch (Type)
{
case EconomyType.Plugin:
{
var plugin = _instance?.plugins?.Find(Plug);
if (plugin == null) return;
switch (Plug)
{
case "BankSystem":
case "ServerRewards":
plugin.Call(AddHook, player.userID, (int) amount);
break;
default:
plugin.Call(AddHook, player.userID, amount);
break;
}
break;
}
case EconomyType.Item:
{
var am = (int) amount;
var item = ToItem(am);
if (item == null) return;
player.GiveItem(item);
break;
}
}
}
public bool RemoveBalance(BasePlayer player, double amount)
{
switch (Type)
{
case EconomyType.Plugin:
{
if (ShowBalance(player) < amount) return false;
var plugin = _instance?.plugins.Find(Plug);
if (plugin == null) return false;
switch (Plug)
{
case "BankSystem":
case "ServerRewards":
plugin.Call(RemoveHook, player.userID, (int) amount);
break;
default:
plugin.Call(RemoveHook, player.userID, amount);
break;
}
return true;
}
case EconomyType.Item:
{
var playerItems = player.inventory.AllItems();
var am = (int) amount;
if (ItemCount(playerItems, ShortName, Skin) < am) return false;
Take(playerItems, ShortName, Skin, am);
return true;
}
default:
return false;
}
}
private Item ToItem(int amount)
{
var item = ItemManager.CreateByName(ShortName, amount, Skin);
if (item == null)
{
Debug.LogError($"Error creating item with ShortName: '{ShortName}'");
return null;
}
if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;
return item;
}
}
private class EconomyConf : EconomyTemplate
{
[JsonProperty(PropertyName = "Show Balance")]
public bool Show;
}
private class CustomCurrency : EconomyTemplate
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Cost Format")]
public string CostFormat;
}
private abstract class CaseTemplate
{
[JsonProperty(PropertyName = "ID")] public int ID;
[JsonProperty(PropertyName = "Title")] public string Title;
[JsonProperty(PropertyName = "Image")] public string Image;
[JsonProperty(PropertyName = "Permission")]
public string Permission;
[JsonProperty(PropertyName = "Cooldown")]
public float CooldownTime;
[JsonProperty(PropertyName = "Items", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ItemInfo> Items;
public bool HasCase(BasePlayer player, int caseId)
{
return _instance.GetPlayerData(player).Cases.ContainsKey(caseId);
}
public int CaseAmount(BasePlayer player, int caseId)
{
return _instance.GetPlayerData(player).Cases[caseId];
}
public void Log(BasePlayer player, ItemInfo itemInfo)
{
_instance._config.Logs.Log(_instance?.Msg(player, LogOpenedCase).Replace("{username}", player.displayName).Replace("{steamid}", player.UserIDString).Replace("{casename}", Title).Replace("{item}", itemInfo.LogFormatted(player)));
}
}
private class BonusCaseInfo : CaseInfo
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
}
private class CaseInfo : CaseTemplate, ICloneable, IDisposable
{
[JsonProperty(PropertyName = "Cost")] public int Cost;
[JsonProperty(PropertyName = "Custom Currency")]
public CustomCurrency CustomCurrency;
public object Clone()
{
return MemberwiseClone();
}
public void Dispose()
{
//null
}
}
private enum ItemType
{
Item,
Command,
Plugin
}
private class ItemInfo
{
[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
public ItemType Type;
[JsonProperty(PropertyName = "ID")] public int ID;
[JsonProperty(PropertyName = "Image")] public string Image;
[JsonProperty(PropertyName = "Title")] public string Title;
[JsonProperty(PropertyName = "Command (%steamid%)")]
public string Command;
[JsonProperty(PropertyName = "Plugin")]
public PluginItem Plugin;
[JsonProperty(PropertyName = "Display Name (empty - default)")]
public string DisplayName;
[JsonProperty(PropertyName = "ShortName")]
public string ShortName;
[JsonProperty(PropertyName = "Skin")] public ulong Skin;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Chance")]
public float Chance;
#region Definition
[JsonIgnore] private ItemDefinition _definition;
[JsonIgnore]
public ItemDefinition ItemDefinition
{
get
{
if (_definition == null)
_definition = ItemManager.FindItemDefinition(ShortName);
return _definition;
}
}
public void UpdateDefinition()
{
_definition = ItemManager.FindItemDefinition(ShortName);
}
#endregion
public string GetName()
{
if (!string.IsNullOrEmpty(Title))
return Title;
if (!string.IsNullOrEmpty(DisplayName))
return DisplayName;
var def = ItemManager.FindItemDefinition(ShortName);
if (!string.IsNullOrEmpty(ShortName) && def != null)
return def.displayName.translated;
return string.Empty;
}
public void Get(BasePlayer player, int count = 1)
{
switch (Type)
{
case ItemType.Item:
ToItem(player, count);
break;
case ItemType.Command:
ToCommand(player, count);
break;
case ItemType.Plugin:
Plugin.Get(player, count);
break;
}
}
private void ToItem(BasePlayer player, int count)
{
if (ItemDefinition == null)
{
Debug.LogError($"Error creating item with ShortName '{ShortName}'");
return;
}
GetStacks(ItemDefinition, Amount * count)?.ForEach(stack =>
{
var newItem = ItemManager.Create(ItemDefinition, stack, Skin);
if (newItem == null)
{
_instance?.PrintError($"Error creating item with ShortName '{ShortName}'");
return;
}
if (!string.IsNullOrEmpty(DisplayName)) newItem.name = DisplayName;
player.GiveItem(newItem, BaseEntity.GiveItemReason.PickedUp);
});
}
private void ToCommand(BasePlayer player, int count)
{
for (var i = 0; i < count; i++)
{
var command = Command.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace(
"%username%",
player.displayName, StringComparison.OrdinalIgnoreCase);
foreach (var check in command.Split('|')) _instance?.Server.Command(check);
}
}
private static List<int> GetStacks(ItemDefinition item, int amount)
{
var list = Pool.GetList<int>();
var maxStack = item.stackable;
if (maxStack == 0) maxStack = 1;
while (amount > maxStack)
{
amount -= maxStack;
list.Add(maxStack);
}
list.Add(amount);
return list;
}
public string LogFormatted(BasePlayer player)
{
return _instance?.Msg(player, LogItem).Replace("{name}", GetName()).Replace("{amount}", Amount.ToString()).Replace("{shortname}", ShortName) ?? string.Empty;
}
}
private class PluginItem
{
[JsonProperty(PropertyName = "Hook")] public string Hook;
[JsonProperty(PropertyName = "Plugin name")]
public string Plugin;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
public void Get(BasePlayer player, int count = 1)
{
var plug = _instance?.plugins.Find(Plugin);
if (plug == null)
{
_instance?.PrintError($"Plugin '{Plugin}' not found !!! ");
return;
}
switch (Plugin)
{
case "Economics":
{
plug.Call(Hook, player.userID, (double) Amount * count);
break;
}
default:
{
plug.Call(Hook, player.userID, Amount * count);
break;
}
}
}
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch
{
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
protected override void LoadDefaultConfig()
{
_config = new Configuration();
}
#endregion
#region Data
private PluginData _data;
private void SaveData()
{
SavePlayers();
SaveCooldowns();
}
private void SavePlayers()
{
Interface.Oxide.DataFileSystem.WriteObject(Name, _data);
}
private void SaveCooldowns()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}_Cooldowns", Cooldowns);
}
private void LoadData()
{
try
{
_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
Cooldowns = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, Cooldown>>($"{Name}_Cooldowns");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_data == null) _data = new PluginData();
if (Cooldowns == null) Cooldowns = new Dictionary<ulong, Cooldown>();
}
private class PluginData
{
[JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<ulong, PlayerData> Players = new Dictionary<ulong, PlayerData>();
}
private class PlayerData
{
[JsonProperty(PropertyName = "Last Bonus Time")]
public DateTime LastBonus = new DateTime(1970, 1, 1);
[JsonProperty(PropertyName = "Cases", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<int, int> Cases = new Dictionary<int, int>();
[JsonProperty(PropertyName = "Last PlayTime")]
public double LastPlayTime;
}
private PlayerData GetPlayerData(BasePlayer player)
{
return GetPlayerData(player.userID);
}
private PlayerData GetPlayerData(ulong member)
{
if (!_data.Players.ContainsKey(member))
_data.Players.Add(member, new PlayerData());
return _data.Players[member];
}
#endregion
#region Hooks
private void Init()
{
_instance = this;
LoadData();
if (!_config.TimeCasesSettings.Enable)
Unsubscribe(nameof(OnPlayerConnected));
}
private void OnServerInitialized()
{
PrintWarning("\n-----------------------------\n" +
" Author - Sempai#3239\n" +
" VK - https://vk.com/rustnastroika\n" +
" Discord - https://discord.gg/5DPTsRmd3G\n" +
"-----------------------------");
LoadItems();
LoadImages();
CheckOnDuplicates();
FillItems();
AddCovalenceCommand(_config.Commands, nameof(CmdCases));
AddCovalenceCommand("givecase", nameof(CmdGiveCase));
permission.RegisterPermission(PERM_EDIT, this);
if (_config.TimeCasesSettings.Enable || _config.PlaytimeTrackerConf.Enabled)
{
if (_config.TimeCasesSettings.Enable)
foreach (var player in BasePlayer.activePlayerList)
OnPlayerConnected(player);
timer.Every(1, TimeHandler);
}
if (_config.Cases.Exists(x => x.CooldownTime > 0)) timer.Every(1, CooldownController);
}
private void OnServerSave()
{
timer.In(Random.Range(2, 7), SavePlayers);
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, Layer);
CuiHelper.DestroyUi(player, Layer + ".Modal");
OnPlayerDisconnected(player, string.Empty);
}
SaveData();
_instance = null;
}
private void OnPlayerDisconnected(BasePlayer player, string reason)
{
if (player == null) return;
_editByPlayer.Remove(player);
player.GetComponent<OpenCase>()?.Finish(true);
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null) return;
TimePlayers[player] = Time.time;
}
#region Wipe
private void OnNewSave(string filename)
{
if (_config.Wipe.Players)
{
_data.Players.Clear();
SavePlayers();
}
if (_config.Wipe.Cooldowns)
{
Cooldowns.Clear();
SaveCooldowns();
}
}
#endregion
#endregion
#region Commands
private void CmdCases(IPlayer cov, string command, string[] args)
{
var player = cov?.Object as BasePlayer;
if (player == null) return;
if (!string.IsNullOrEmpty(_config.Permission) &&
!permission.UserHasPermission(player.UserIDString, _config.Permission))
{
SendNotify(player, NoPermissions, 1);
return;
}
OpenCase openCase;
if (player.TryGetComponent(out openCase) && openCase.Started) return;
MainUI(player, first: true);
}
private void CmdGiveCase(IPlayer cov, string command, string[] args)
{
if (args.Length < 3)
{
cov.Reply($"Error syntax! Use: {command} <steamid> <caseid> <amount>");
return;
}
var isAll = false;
ulong target;
if (!ulong.TryParse(args[0], out target))
{
if (args[0] == "*")
isAll = true;
else
return;
}
int caseId, amount;
if (!int.TryParse(args[1], out caseId) || !int.TryParse(args[2], out amount)) return;
if (isAll)
{
foreach (var player in BasePlayer.activePlayerList) GiveCase(player, caseId, amount);
cov.Reply($"{BasePlayer.activePlayerList.Count} players received case {caseId} ({amount} pcs.)");
}
else
{
GiveCase(target, caseId, amount);
cov.Reply($"Player `{target}` received case {caseId} ({amount} pcs.)");
}
}
[ConsoleCommand("UI_Cases")]
private void CmdConsoleCases(ConsoleSystem.Arg arg)
{
var player = arg?.Player();
if (player == null || !arg.HasArgs()) return;
switch (arg.Args[0])
{
case "stopedit":
{
_editByPlayer.Remove(player);
break;
}
case "edit":
{
int caseId;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out caseId)) return;
_editByPlayer[player] = new EditData(caseId);
EditCaseUI(player);
break;
}
case "saveedit":
{
var editData = _editByPlayer[player];
if (editData.Generated)
{
_config.Cases.Add(editData.CaseInfo);
}
else
{
var oldCase = FindCaseById(editData.CaseInfo.ID);
var newCase = editData.CaseInfo;
var index = _config.Cases.IndexOf(oldC
// ... [Code preview truncated due to length. Full source in attached file] ...