C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using ConVar;
using Newtonsoft.Json;
using System.Collections;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core;
using UnityEngine;
using System.Text;
using System;
using Object = System.Object;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Networking;
namespace Oxide.Plugins {
[Info("IQCases", "Mercury", "2.4.74")]
[Description("Кейсы на ваш сервер")]
public class IQCases : RustPlugin {
Boolean API_IS_CASE_EXIST(String CaseKey) => config.CasesPresets.ContainsKey(CaseKey);
private void OnServerInitialized() {
_ = this;
//Load your images here
ImageUi.Initialize();
ImageUi.DownloadImages();
foreach (KeyValuePair<String, Configuration.CasesPreset> Cases in config.CasesPresets) {
if(!CaseKeys.Contains(Cases.Key)) CaseKeys.Add(Cases.Key);
if(!String.IsNullOrWhiteSpace(Cases.Value.RestrictionsSettings.Permissions) && !permission.PermissionExists(Cases.Value.RestrictionsSettings.Permissions, this)) permission.RegisterPermission(Cases.Value.RestrictionsSettings.Permissions, this);
}
foreach (Configuration.DefaultCasePlayer defaultCasePlayer in config.DefaultCasePlayers) {
if(!String.IsNullOrWhiteSpace(defaultCasePlayer.Permissions) && !permission.PermissionExists(defaultCasePlayer.Permissions, this)) permission.RegisterPermission(defaultCasePlayer.Permissions, this);
}
foreach (List<Configuration.DropCases> DropCase in config.DropCasesList.Values) {
foreach (Configuration.DropCases cases in DropCase) {
if (!String.IsNullOrWhiteSpace(cases.Permissions) && !permission.PermissionExists(cases.Permissions, this)) permission.RegisterPermission(cases.Permissions, this);
}
}
if (config.DropCasesList.Count == 0) {
Unsubscribe("OnLootEntity");
Unsubscribe("OnEntityDeath");
}
Puts(LanguageEn ? $"Loaded {CaseKeys.Count} cases" : $"Загружено {CaseKeys.Count} кейсов");
foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerConnected(player);
}
private new void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["UI_TITLE_CASE_INFO_ITEMS"]
= "<b>Possible items and their chances in this case</b>", ["UI_TUBLER_INVENTORY_PLUGIN"] = "To plugin inventory", ["UI_TUBLER_INVENTORY_PLAYER"] = "Your inventory", ["UI_PROFILE_TITLE_YOUR_AMOUNT_CASE"] = "Quantity cases", ["UI_PROFILE_DESCRIPTION_YOUR_AMOUNT_CASE"] = "{0} piece", ["UI_PROFILE_TITLE_YOUR_INVENTORY"] = "Your inventory", ["UI_PROFILE_DESCRIPTION_YOUR_INVENTORY"] = "clickable", ["UI_PROFILE_TITLE_IQECONOMIC_BALANCE"] = "Balance:", ["UI_PROFILE_DESCRIPTION_AMOUNT_IQECONOMIC_BALANCE"] = "{0}", ["UI_ITEM_LIST_ITEM_NAME"] = "<b>Item</b>", ["UI_ITEM_LIST_COMMAND_NAME"] = "<b>Reward</b>", ["UI_CASE_BUTTON_OPEN_CASE"] = "<b>OPEN CASE</b>", ["UI_CASE_BUTTON_NO_OPEN_AMOUNT_CASE"] = "<b><size=17>NOT ENOUGH CASES</size></b>", ["UI_CASE_BUTTON_SELL_BUTTON"] = "<b>SELL</b>", ["UI_CASE_BUTTON_BUY_BUTTON"] = "<b>BUY</b>", ["UI_CASE_TITLE_INVENTORY"] = "<b>INVENTORY</b>", ["UI_CASE_DESCRIPTION_INVENTORY"] = "This is where all your belongings knocked out of cases go.\nYou can pick them up at any time!", ["UI_CASE_BUTTON_BACK_CASE"] = "Back", ["UI_CASE_INITIALIZE"] = "Cases are currently being initialized, possibly later", ["UI_CASE_IQRANK_BLOCKED"] = "Rank required {0}", ["UI_CASE_PERMISSION_BLOCKED"] = "Not permissions", ["CASE_MESSAGE_FIND_CASE"] = "You have successfully found a case, check your cases!", ["CASE_MESSAGE_NO_DUEL"] = "You cannot use cases during a duel", ["CASE_MESSAGE_FULL_INVENTORY"] = "Your inventory is full!\nItem has been dropped on the ground!", ["UI_ITEM_TIME_DAYS"] = "D", ["UI_ITEM_TIME_HOURSE"] = "H", ["UI_ITEM_TIME_MINUTES"] = "M", ["UI_ITEM_TIME_SECONDS"] = "S",
}
, this);
lang.RegisterMessages(new Dictionary<string, string> {
["UI_TITLE_CASE_INFO_ITEMS"]
= "<b>Возможные предметы и их шансы в этом кейсе</b>", ["UI_TUBLER_INVENTORY_PLUGIN"] = "В инвентарь плагина", ["UI_TUBLER_INVENTORY_PLAYER"] = "В ваш инвентарь", ["UI_PROFILE_TITLE_YOUR_AMOUNT_CASE"] = "Количество кейсов", ["UI_PROFILE_DESCRIPTION_YOUR_AMOUNT_CASE"] = "{0} штук", ["UI_PROFILE_TITLE_YOUR_INVENTORY"] = "Ваш инвентарь", ["UI_PROFILE_DESCRIPTION_YOUR_INVENTORY"] = "кликабельно", ["UI_PROFILE_TITLE_IQECONOMIC_BALANCE"] = "Баланс:", ["UI_PROFILE_DESCRIPTION_AMOUNT_IQECONOMIC_BALANCE"] = "{0}", ["UI_ITEM_LIST_ITEM_NAME"] = "<b>Предмет</b>", ["UI_ITEM_LIST_COMMAND_NAME"] = "<b>Награда</b>", ["UI_CASE_BUTTON_OPEN_CASE"] = "<b>ОТКРЫТЬ КЕЙС</b>", ["UI_CASE_BUTTON_NO_OPEN_AMOUNT_CASE"] = "<b><size=17>НЕДОСТАТОЧНО КЕЙСОВ</size></b>", ["UI_CASE_BUTTON_SELL_BUTTON"] = "<b>ПРОДАТЬ</b>", ["UI_CASE_BUTTON_BUY_BUTTON"] = "<b>КУПИТЬ</b>", ["UI_CASE_TITLE_INVENTORY"] = "<b>ИНВЕНТАРЬ</b>", ["UI_CASE_DESCRIPTION_INVENTORY"] = "Сюда попадают все ваши вещи выбитые с кейсов.\nВы можете забрать их в любой момент!", ["UI_CASE_BUTTON_BACK_CASE"] = "Вернуться", ["UI_CASE_INITIALIZE"] = "Кейсы в данный момент инициализируются, попробуйте позже", ["UI_CASE_IQRANK_BLOCKED"] = "Требуется ранг {0}", ["UI_CASE_PERMISSION_BLOCKED"] = "Недостаточно прав", ["CASE_MESSAGE_FIND_CASE"] = "Вы успешно нашли кейс, проверьте свои кейсы!", ["CASE_MESSAGE_NO_DUEL"] = "Вы не можете ипользовать кейсы во время дуэли", ["CASE_MESSAGE_FULL_INVENTORY"] = "Ваш инвентарь переполнен!\nПредмет выброшен на землю!", ["UI_ITEM_TIME_DAYS"] = "Д", ["UI_ITEM_TIME_HOURSE"] = "Ч", ["UI_ITEM_TIME_MINUTES"] = "М", ["UI_ITEM_TIME_SECONDS"] = "С",
}
, this, "ru");
}
private void OnPlayerConnected(BasePlayer player) => RegisteredDataUser(player.userID);
private void DrawUI_InventoryPlayer(BasePlayer player) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_INVENTORY_PLAYER");
if (Interface == null) return;
Interface = Interface.Replace("%UI_CASE_DESCRIPTION_INVENTORY%", GetLang("UI_CASE_DESCRIPTION_INVENTORY", player.UserIDString));
Interface = Interface.Replace("%UI_CASE_TITLE_INVENTORY%", GetLang("UI_CASE_TITLE_INVENTORY", player.UserIDString));
Interface = Interface.Replace("%UI_CASE_BUTTON_BACK_CASE%", GetLang("UI_CASE_BUTTON_BACK_CASE", player.UserIDString));
Interface = Interface.Replace("%UI_PROFILE_DESCRIPTION_YOUR_INVENTORY%", GetLang("UI_PROFILE_DESCRIPTION_YOUR_INVENTORY", player.UserIDString));
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_CASES_MENU);
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_CASES_MENU_INVENTORY);
CuiHelper.AddUi(player, Interface);
DrawUI_InventoryPlayer_Pages(player);
DrawUI_ShowItems_Inventory(player);
}
[ConsoleCommand("case")]
private void AdminCaseCommand(ConsoleSystem.Arg arg) {
if (!FullInit) return;
BasePlayer player = arg.Player();
if(player != null) if (!player.IsAdmin) return;
if (!arg.HasArgs(3)) return;
String NamaOrID = arg.GetString(1);
if(String.IsNullOrWhiteSpace(NamaOrID)) {
PrintWarning(LanguageEn ? "Enter Nickname or SteamID" : "Введите ник или SteamID");
return;
}
IPlayer iPlayer = covalence.Players.FindPlayer(NamaOrID);
if(iPlayer == null) {
PrintWarning(LanguageEn ? $"This player does not exist" : $"Такого игрока не существует");
return;
}
String CaseKey = arg.GetString(2);
if (String.IsNullOrWhiteSpace(CaseKey) || !CaseKeys.Contains(CaseKey)) {
PrintWarning(LanguageEn ? "Case with such key does not exist" : "Кейса с таким ключем не существует");
return;
}
Int32 Amount = arg.GetInt(3, -1);
if (Amount == -1) {
PrintWarning(LanguageEn ? "The second argument is not a number!" : "Второй аргумент не является числом!");
return;
}
UInt64 PlayerID = UInt64.Parse(iPlayer.Id);
switch (arg.GetString(0)) {
case "give" : {
GiveCases(PlayerID, CaseKey, Amount);
Puts(LanguageEn ? $"The player successfully received a case {CaseKey} in the amount of {Amount}" : $"Игрок успешно получил кейс {CaseKey} в количестве {Amount}");
break;
}
case "remove" : {
if (!RemoveCases(PlayerID, CaseKey, Amount)) {
Puts(LanguageEn ? $"Player has no cases with key {CaseKey}" : $"У игрока нет кейсов с ключем {CaseKey}");
return;
}
Puts(LanguageEn ? $"You have successfully removed the {Amount} of the {CaseKey} case from the player" : $"Вы успешно удалили {Amount} кейсов {CaseKey} у игрока");
break;
}
}
}
private void TakeReward(BasePlayer player, InformationPlayer.RewardPreset rewardPreset) {
if (!DataPlayer[player.userID].InventoryPlayer.Contains(rewardPreset)) {
PrintError(LanguageEn ? "Could not determine the item that arose with the developer, and the settings and data file came." : "Не удалось определить предмет, свяжитесь с разработчиком и пришлите конфигурацию и дата-файл");
return;
}
DataPlayer[player.userID].InventoryPlayer.Remove(rewardPreset);
GiveReward(player, rewardPreset);
DrawUI_ShowItems_Inventory(player);
}
private class ImageUi {
private static Coroutine coroutineImg = null;
private static Dictionary<String, String> Images = new Dictionary<String, String>();
private static List<String> KeyImages = new List<String>();
public static void DownloadImages() {
coroutineImg = ServerMgr.Instance.StartCoroutine(AddImage());
}
private static IEnumerator AddImage() {
if (_ == null) yield break;
_.PrintWarning(LanguageEn ? "We generate the interface, wait ~10-15 seconds!" : "Генерируем интерфейс, ожидайте ~10-15 секунд!");
foreach (String URL in KeyImages) {
String KeyName = URL;
if (KeyName == null) throw new ArgumentNullException(nameof(KeyName));
UnityWebRequest www = UnityWebRequestTexture.GetTexture(URL);
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError) {
_.PrintWarning($"Image download error! Error: {www.error}, Image name: {KeyName}");
www.Dispose();
coroutineImg = null;
yield break;
}
Texture2D texture = DownloadHandlerTexture.GetContent(www);
if (texture != null) {
Byte[] bytes = texture.EncodeToPNG();
String image = FileStorage.server.Store(bytes, FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
if (!Images.ContainsKey(KeyName)) Images.Add(KeyName, image);
else Images[KeyName] = image;
UnityEngine.Object.DestroyImmediate(texture);
}
www.Dispose();
yield return CoroutineEx.waitForSeconds(0.02f);
}
yield return CoroutineEx.waitForSeconds(0.02f);
coroutineImg = null;
_interface = new InterfaceBuilder();
_.PrintWarning(LanguageEn ? "Interface loaded successfully!" : "Интерфейс успешно загружен!");
_.FullInit = true;
}
public static String GetImage(String ImgKey) => Images.ContainsKey(ImgKey) ? Images[ImgKey] : _.GetImage("LOADING");
public static String GetRareImage(Int32 Rare) {
String Image = String.Empty;
Configuration.Interface @interface = config.InterfaceSettings;
foreach (KeyValuePair<Int32, String> RareImages in @interface.RareBackground) {
if (Rare < RareImages.Key) continue;
Image = RareImages.Value;
break;
}
if (String.IsNullOrWhiteSpace(Image)) Image = @interface.RareBackground.OrderBy(x => x.Key).First().Value;
return Image;
}
public static void Initialize() {
KeyImages = new List<String>();
Images = new Dictionary<String, String>();
Configuration.Interface @interface = config.InterfaceSettings;
if (!KeyImages.Contains(@interface.TumblerLeft)) KeyImages.Add(@interface.TumblerLeft);
if (!KeyImages.Contains(@interface.TumblerRight)) KeyImages.Add(@interface.TumblerRight);
if (!KeyImages.Contains(@interface.PanelCasesInfoAmount)) KeyImages.Add(@interface.PanelCasesInfoAmount);
if (!KeyImages.Contains(@interface.PanelCasesInventoryPanel)) KeyImages.Add(@interface.PanelCasesInventoryPanel);
if (!KeyImages.Contains(@interface.PanelCasesBalancePanel)) KeyImages.Add(@interface.PanelCasesBalancePanel);
if (!KeyImages.Contains(@interface.EffectCases)) KeyImages.Add(@interface.EffectCases);
foreach (KeyValuePair<String, Configuration.CasesPreset> preset in config.CasesPresets) {
if(!KeyImages.Contains(preset.Value.PNGCase)) KeyImages.Add(preset.Value.PNGCase);
foreach (Configuration.CasesPreset.RewardPreset rewardPreset in preset.Value.RewardPresets) {
if(!String.IsNullOrWhiteSpace(rewardPreset.PNGReward) && !KeyImages.Contains(rewardPreset.PNGReward)) KeyImages.Add(rewardPreset.PNGReward);
}
}
if (!KeyImages.Contains(@interface.BackPage)) KeyImages.Add(@interface.BackPage);
if (!KeyImages.Contains(@interface.NextPage)) KeyImages.Add(@interface.NextPage);
if (!KeyImages.Contains(@interface.OpenCaseButton)) KeyImages.Add(@interface.OpenCaseButton);
if (!KeyImages.Contains(@interface.BuyCaseButton)) KeyImages.Add(@interface.BuyCaseButton);
if (!KeyImages.Contains(@interface.SellCaseButton)) KeyImages.Add(@interface.SellCaseButton);
if (!KeyImages.Contains(@interface.BlockPanelButton)) KeyImages.Add(@interface.BlockPanelButton);
if (!KeyImages.Contains(@interface.RareMiniIcon)) KeyImages.Add(@interface.RareMiniIcon);
if (!KeyImages.Contains(@interface.NoRareBackground)) KeyImages.Add(@interface.NoRareBackground);
foreach (String PNGRares in @interface.RareBackground.Values) {
if (!KeyImages.Contains(PNGRares)) KeyImages.Add(PNGRares);
}
}
public static void Unload() {
coroutineImg = null;
foreach (KeyValuePair<String, String> item in Images) FileStorage.server.RemoveExact(UInt32.Parse(item.Value), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID, 0U);
KeyImages.Clear();
KeyImages = null;
Images.Clear();
Images = null;
}
}
private Dictionary<BasePlayer, LocalRepository> LocalRepositoryPlayer = new Dictionary<BasePlayer, LocalRepository>();
private String Format(Int32 units, String form1, String form2, String form3) {
var tmp = units % 10;
if (units >= 5 && units <= 20 || tmp >= 5 && tmp <= 9) return $"{units}{form1}";
if (tmp >= 2 && tmp <= 4) return $"{units}{form2}";
return $"{units}{form3}";
}
Boolean API_IS_CASE_PLAYER(BasePlayer player, String CaseKey) => API_GET_AMOUNT_CASE(player, CaseKey) != 0;
private const Boolean LanguageEn = false;
private void OnLootEntity(BasePlayer player, BaseEntity entity) {
if (entity == null || player == null) return;
if (entity as StorageContainer == null) return;
if (entity.OwnerID >= 7656000000) return;
if (entity.net == null) return;
UInt64 NetID = entity.net.ID.Value;
if (LootersListCrateID.Contains(NetID)) return;
SearchCaseLootable(player, entity.ShortPrefabName);
LootersListCrateID.Add(NetID);
}
private String GetImage(String fileName, UInt64 skin = 0) {
String imageId = (String)plugins.Find("ImageLibrary").CallHook("ImageUi.GetImage", fileName, skin);
return !String.IsNullOrEmpty(imageId) ? imageId : String.Empty;
}
private void MoveToInventory(BasePlayer player, Configuration.CasesPreset.RewardPreset Reward) {
List<InformationPlayer.RewardPreset> Inventory = DataPlayer[player.userID].InventoryPlayer;
if (Reward.Type == TypeReward.Item) {
ItemDefinition ItemDef = ItemManager.FindItemDefinition(Reward.ItemSetting.Shortname);
if (ItemDef != null) if (ItemDef.category == ItemCategory.Resources || ItemDef.category == ItemCategory.Medical || ItemDef.category == ItemCategory.Food || ItemDef.category == ItemCategory.Ammunition || ItemDef.category == ItemCategory.Component) {
InformationPlayer.RewardPreset InventoryItem = Inventory.FirstOrDefault(x => x.ItemSetting.Shortname.Equals(Reward.ItemSetting.Shortname) && x.ItemSetting.SkinID == Reward.ItemSetting.SkinID);
if (InventoryItem != null) InventoryItem.ItemSetting.Amount += Reward.ItemSetting.Amounts.GetAmount;
else DataPlayer[player.userID].InventoryPlayer.Add(DataPlayer[player.userID].GenericRewardPreset(Reward));
return;
}
}
DataPlayer[player.userID].InventoryPlayer.Add(DataPlayer[player.userID].GenericRewardPreset(Reward));
}
private void GiveCases(UInt64 playerID, String CaseKey, Int32 Amount = 1) {
if (!CaseKeys.Contains(CaseKey)) return;
RegisteredDataUser(playerID);
if (DataPlayer[playerID].CasesPlayer.ContainsKey(CaseKey)) DataPlayer[playerID].CasesPlayer[CaseKey] += Amount;
else DataPlayer[playerID].CasesPlayer.Add(CaseKey, Amount);
BasePlayer player = BasePlayer.FindByID(playerID);
if (player == null) return;
SendChat(GetLang("CASE_MESSAGE_FIND_CASE", player.UserIDString), player);
}
private class LocalRepository {
public void SetCooldown() => CooldownTakeItem = CurrentTime + 1f;
private Double CooldownTakeItem;
private Double CooldownEffects;
public Boolean IsCooldownTake => CooldownTakeItem >= CurrentTime;
public Boolean IsOpenedCase;
public void SetCooldownEffect() => CooldownEffects = CurrentTime + 1f;
public Boolean IsCooldownEffect => CooldownEffects >= CurrentTime;
}
Int32 API_GET_AMOUNT_CASE(BasePlayer player, String CaseKey) {
if (!DataPlayer.ContainsKey(player.userID)) return 0;
return DataPlayer[player.userID].GetAmountCase(CaseKey);
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
foreach (KeyValuePair<string, Configuration.CasesPreset> configCasesPreset in config.CasesPresets) {
if (configCasesPreset.Value.caseName == null) {
configCasesPreset.Value.caseName = new Configuration.CasesPreset.NameCases() {
NameRussia = "", NameEnglish = "",
}
;
}
if (configCasesPreset.Value.caseName.NameEnglish == null) configCasesPreset.Value.caseName.NameEnglish = "";
if (configCasesPreset.Value.caseName.NameRussia == null) configCasesPreset.Value.caseName.NameRussia = "";
}
}
catch {
PrintWarning(LanguageEn ? "Error #58 reading configuration 'oxide/config/{Name}', creating a new configuration!!" : $"Ошибка #58 чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
NextTick(SaveConfig);
}
private List<UInt64> LootersListCrateID = new List<UInt64>();
private Boolean GetRandomDrop(Int32 RandomInt) {
Int32 Random = Oxide.Core.Random.Range(0, 100);
return RandomInt >= Random;
}
private void DrawUI_ShowCases(BasePlayer player, Int32 Page) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_CASES");
if (Interface == null) return;
String SelectCaseKey = CaseKeys[Page];
String BackCaseKey = Page - 1 >= 0 ? CaseKeys[Page - 1] : CaseKeys[CaseKeys.Count - 1];
String NextCaseKey = Page + 1 >= CaseKeys.Count ? CaseKeys[0] : CaseKeys[Page + 1];
Configuration.CasesPreset CaseCentral = config.CasesPresets[SelectCaseKey];
Configuration.CasesPreset CaseBack = config.CasesPresets[BackCaseKey];
Configuration.CasesPreset CaseNext = config.CasesPresets[NextCaseKey];
Boolean IsBuy = CaseCentral.EconomicSettings.IsBuy && GetBalance(player.userID) >= CaseCentral.EconomicSettings.PriceBuyCase;
Boolean IsSell = CaseCentral.EconomicSettings.IsSell && DataPlayer[player.userID].GetAmountCase(SelectCaseKey) > 0;
Interface = Interface.Replace("%THREE_CASE_PNG%", ImageUi.GetImage(CaseBack.PNGCase));
Interface = Interface.Replace("%TWO_CASE_PNG%", ImageUi.GetImage(CaseNext.PNGCase));
Interface = Interface.Replace("%CENTRAL_CASE_PNG%", ImageUi.GetImage(CaseCentral.PNGCase));
Interface = Interface.Replace("%CASENAME%", CaseCentral.caseName.GetCaseName(player));
Interface = Interface.Replace("%UI_CASE_BUTTON_SELL_BUTTON%", GetLang("UI_CASE_BUTTON_SELL_BUTTON", player.UserIDString));
Interface = Interface.Replace("%COMMAND_SELL_CASE%", !IsSell ? "" : $"case.func sell.case.economic {SelectCaseKey}");
Interface = Interface.Replace("%UI_CASE_BUTTON_BUY_BUTTON%", GetLang("UI_CASE_BUTTON_BUY_BUTTON", player.UserIDString));
Interface = Interface.Replace("%COMMAND_BUY_CASE%", !IsBuy ? "" : $"case.func buy.case.economic {SelectCaseKey}");
Interface = Interface.Replace("%PRICE_BUY%", !IsBuy ? "" : $"<b>-{CaseCentral.EconomicSettings.PriceBuyCase}</b>");
Interface = Interface.Replace("%PRICE_SELL%", !IsSell ? "" : $"<b>+{CaseCentral.EconomicSettings.PriceSellCase}</b>");
Interface = Interface.Replace("%BACK_PAGE%", $"case.func page.controller {Page - 1}");
Interface = Interface.Replace("%NEXT_PAGE%", $"case.func page.controller {Page + 1}");
CuiHelper.DestroyUi(player, "BackgroundPanelCasesMain");
CuiHelper.AddUi(player, Interface);
DrawUI_UpdateLabels(player, SelectCaseKey);
if (_.IQEconomic || _.Economics) {
if (!IsBuy) DrawUI_BlockButton(player, "BuyCase");
if (!IsSell) DrawUI_BlockButton(player, "SellCase");
}
DrawUI_ShowItems(player, SelectCaseKey);
}
protected override void SaveConfig() => Config.WriteObject(config);
private static InterfaceBuilder _interface;
private class InformationPlayer {
[JsonProperty(LanguageEn ? "Toggle switch for issuing items (true - plugin inventory / false - player inventory)" : "Тумблер выдачи предметов (true - инвентарь плагина/false - инвентарь игрока)")]
public Boolean SwitchTakeInventory = false;
[JsonProperty(LanguageEn ? "Cases [Key] - Amount" : "Кейсы [Key] - Amount")]
public Dictionary<String, Int32> CasesPlayer = new Dictionary<String, Int32>();
[JsonProperty(LanguageEn ? "Inventory player" : "Инвентарь игрока")]
public List<RewardPreset> InventoryPlayer = new List<RewardPreset>();
internal class RewardPreset {
[JsonProperty(LanguageEn ? "Select reward type: 0 - Item, 1 - Command" : "Выберите тип награды : 0 - Предмет, 1 - Команда")]
public TypeReward Type;
[JsonProperty(LanguageEn ? "The displayed chance of getting this reward" : "Отображаемый шанс выпадения данной награды")]
public Int32 VisualRare;
[JsonProperty(LanguageEn ? "PNG for reward" : "PNG для награды")]
public String PNGReward;
[JsonProperty(LanguageEn ? "Infromation Item" : "Данные о предмете")]
public ItemPreset ItemSetting = new ItemPreset();
[JsonProperty(LanguageEn ? "Information Command" : "Данные о команде")]
public CommandPreset CommandSetting = new CommandPreset();
internal class CommandPreset {
[JsonProperty(LanguageEn ? "Item name in UI (if left blank, values from lang will be used)" : "Название предмета в UI (если оставить пустым будут браться значения из lang)")]
public String DisplayName;
[JsonProperty(LanguageEn ? "Console command (%STEAMID% - will be replaced by the player's Steam64ID)" : "Консольная команда (%STEAMID% - заменится на Steam64ID игрока)")]
public String Command;
[JsonProperty(LanguageEn ? "Seconds (only affects the visual display)" : "Секунды (влияет только на визуальное отображение)")]
public Int32 SecondCommand;
[JsonProperty(LanguageEn ? "Amount (affects visual display only)" : "Количество (влияет только на визуальное отображение)")]
public Int32 ItemAmount;
public String GetAmountLabel(BasePlayer player) => SecondCommand == 0 ? $"x{ItemAmount}" : _.FormatTime(TimeSpan.FromSeconds(SecondCommand), player.UserIDString);
}
internal class ItemPreset {
[JsonProperty(LanguageEn ? "Item name in UI (if left blank, values from lang will be used)" : "Название предмета в UI (если оставить пустым будут браться значения из lang)")]
public String DisplayName;
[JsonProperty(LanguageEn ? "Is this a blueprint? true - yes/false - no" : "Это чертеж? true - да/false - нет")]
public Boolean IsBlueprint;
[JsonProperty(LanguageEn ? "Shortname item" : "Shortname предмета")]
public String Shortname;
[JsonProperty(LanguageEn ? "SkinID item" : "SkinID предмета")]
public UInt64 SkinID;
[JsonProperty(LanguageEn ? "Amount" : "Количество")]
public Int32 Amount;
[JsonIgnore]
public String GetAmountLabel => $"x{Amount}";
}
}
public RewardPreset GenericRewardPreset(Configuration.CasesPreset.RewardPreset Reward) {
RewardPreset ResultReward = new RewardPreset {
Type = Reward.Type, VisualRare = Reward.VisualRare, PNGReward = Reward.PNGReward, ItemSetting = new RewardPreset.ItemPreset {
DisplayName = Reward.ItemSetting.DisplayName, IsBlueprint = Reward.ItemSetting.IsBlueprint, Shortname = Reward.ItemSetting.Shortname, SkinID = Reward.ItemSetting.SkinID, Amount = Reward.ItemSetting.Amounts.GetAmount
}
, CommandSetting = new RewardPreset.CommandPreset {
DisplayName = Reward.CommandSetting.DisplayName, Command = Reward.CommandSetting.Command, SecondCommand = Reward.CommandSetting.SecondCommand, ItemAmount = Reward.CommandSetting.ItemAmount
}
}
;
return ResultReward;
}
public Int32 GetAmountCase(String CaseKey) {
Int32 Amount = 0;
if (CasesPlayer.ContainsKey(CaseKey)) Amount = CasesPlayer[CaseKey];
return Amount;
}
}
private static StringBuilder sb = new StringBuilder();
void API_GIVE_CASE(UInt64 userID, String CaseKey, Int32 Amount) => GiveCases(userID, CaseKey, Amount);
[ChatCommand("сфыу")]
void ChatCommandOpenUI_RuCommand(BasePlayer player) {
OpenMenuCases(player);
}
static Double CurrentTime => Facepunch.Math.Epoch.Current;
private Boolean IsPermissionBlocked(BasePlayer player, String Permission) => String.IsNullOrWhiteSpace(Permission) || permission.UserHasPermission(player.UserIDString, Permission);
private Boolean RemoveCases(UInt64 playerID, String CaseKey, Int32 Amount = 1) {
if (!CaseKeys.Contains(CaseKey)) return false;
if (!DataPlayer[playerID].CasesPlayer.ContainsKey(CaseKey)) return false;
DataPlayer[playerID].CasesPlayer[CaseKey] -= Amount;
if (DataPlayer[playerID].CasesPlayer[CaseKey] == 0) DataPlayer[playerID].CasesPlayer.Remove(CaseKey);
return true;
}
private void Unload() {
WriteData();
InterfaceBuilder.DestroyAll();
ImageUi.Unload();
_ = null;
}
public enum TypeReward {
Item, Command
}
private Boolean IsRank(UInt64 userID, String Key) {
if (!IQRankSystem) return false;
return (Boolean)IQRankSystem?.Call("API_GET_AVAILABILITY_RANK_USER", userID, Key);
}
private static IQCases _;
private void DrawUI_ItemPNG(BasePlayer player, String Parent, String PNG, String Command = "") {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_ITEM_PNG");
if (Interface == null) return;
Interface = Interface.Replace("%PARENT_RARE%", Parent);
Interface = Interface.Replace("%PNG_ITEM%", PNG);
Interface = Interface.Replace("%COMMAND_TAKE%", Command);
CuiHelper.AddUi(player, Interface);
}
private void OnPlayerDisconnected(BasePlayer player, String reason) {
if (LocalRepositoryPlayer.ContainsKey(player)) LocalRepositoryPlayer.Remove(player);
}
public string GetLang(string LangKey, string userID = null, params object[] args) {
sb.Clear();
if (args != null) {
sb.AppendFormat(lang.GetMessage(LangKey, this, userID), args);
return sb.ToString();
}
return lang.GetMessage(LangKey, this, userID);
}
private void SendChat(String Message, BasePlayer player, Chat.ChatChannel channel = Chat.ChatChannel.Global) {
Configuration.ReferencePlugins.IQChatPreset ChatPrest = config.ReferencePluginsPreset.IQChatSettings;
if (IQChat) if (ChatPrest.UIAlertUse) IQChat?.Call("API_ALERT_PLAYER_UI", player, Message);
else IQChat?.Call("API_ALERT_PLAYER", player, Message, ChatPrest.CustomPrefix, ChatPrest.CustomAvatar);
else player.SendConsoleCommand("chat.add", channel, 0, Message);
}
private void DrawUI_ShowItems(BasePlayer player, String CaseKey) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_ITEMS_PANEL");
if (Interface == null) return;
CuiHelper.DestroyUi(player, "PanelItemCase");
CuiHelper.AddUi(player, Interface);
List<Configuration.CasesPreset.RewardPreset> OrderItems = config.CasesPresets[CaseKey].RewardPresets.OrderByDescending(x => x.VisualRare).ToList();
Int32 X = 0, Y = 0;
for (Int32 i = 0; i < 20; i++) {
Configuration.CasesPreset.RewardPreset Reward = OrderItems.Count - 1 >= i ? OrderItems[i] : null;
DrawUI_ShowItem(player, i, X, Y, Reward);
X++;
if (X != 10) continue;
X = 0;
Y += 1;
}
}
private void DrawUI_OpenedCase(BasePlayer player, Int32 AmountCase, String CaseKey) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_CASE_BUTTON_OPENED");
if (Interface == null) return;
Configuration.CasesPreset.RestrictionsPreset CaseRestriction = config.CasesPresets[CaseKey].RestrictionsSettings;
String RankName = IsRankBlocked(player, CaseRestriction.IQRankKey);
Interface = Interface.Replace("%UI_CASE_BUTTON_OPEN_CASE%", !IsPermissionBlocked(player, CaseRestriction.Permissions) ? GetLang("UI_CASE_PERMISSION_BLOCKED", player.UserIDString) : !String.IsNullOrWhiteSpace(RankName) ? GetLang("UI_CASE_IQRANK_BLOCKED", player.UserIDString, RankName) : AmountCase > 0 ? GetLang("UI_CASE_BUTTON_OPEN_CASE", player.UserIDString) : GetLang("UI_CASE_BUTTON_NO_OPEN_AMOUNT_CASE", player.UserIDString));
Interface = Interface.Replace("%COMMAND_OPEN_CASE%", !IsPermissionBlocked(player, CaseRestriction.Permissions) ? "" : !String.IsNullOrWhiteSpace(RankName) ? "" : AmountCase > 0 ? $"case.func open.case {CaseKey}" : "");
CuiHelper.DestroyUi(player, "OpenCaseBTN");
CuiHelper.AddUi(player, Interface);
}
private void DrawUI_InventoryPlayer_Pages(BasePlayer player, Int32 Page = 0) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_INVENTORY_PLAYER_PAGE");
if (Interface == null) return;
Interface = Interface.Replace("%BACK_PAGE_INVENTORY%", Page == 0 ? "" : $"case.func inventory.page.controller {Page - 1}");
Interface = Interface.Replace("%NEXT_PAGE_INVENTORY%", DataPlayer[player.userID].InventoryPlayer.Count <= (Page + 1) * 40 ? "" : $"case.func inventory.page.controller {Page + 1}");
CuiHelper.DestroyUi(player, "BackPageInventory");
CuiHelper.DestroyUi(player, "NextPageInventory");
CuiHelper.AddUi(player, Interface);
}
public String FormatTime(TimeSpan time, String UserID) {
String Result = String.Empty;
String Days = GetLang("UI_ITEM_TIME_DAYS", UserID);
String Hourse = GetLang("UI_ITEM_TIME_HOURSE", UserID);
String Minutes = GetLang("UI_ITEM_TIME_MINUTES", UserID);
String Seconds = GetLang("UI_ITEM_TIME_SECONDS", UserID);
if (time.Seconds != 0) Result = $"{Format(time.Seconds, Seconds, Seconds, Seconds)}";
if (time.Minutes != 0) Result = $"{Format(time.Minutes, Minutes, Minutes, Minutes)}";
if (time.Hours != 0) Result = $"{Format(time.Hours, Hourse, Hourse, Hourse)}";
if (time.Days != 0) Result = $"{Format(time.Days, Days, Days, Days)}";
return Result;
}
[ConsoleCommand("case.func")]
void ConsoleFuncCommandUI(ConsoleSystem.Arg arg) {
if (!FullInit) return;
BasePlayer player = arg.Player();
if (player == null) return;
if(LocalRepositoryPlayer.ContainsKey(player)) if (LocalRepositoryPlayer[player].IsOpenedCase) return;
InformationPlayer Data = DataPlayer[player.userID];
if (Data == null) return;
String Action = arg.Args[0];
switch (Action) {
case "switch.inventory" : {
Data.SwitchTakeInventory = !Data.SwitchTakeInventory;
DrawUI_Tumbler(player);
break;
}
case "page.controller" : {
Int32 Page = Int32.Parse(arg.Args[1]);
if (Page >= CaseKeys.Count) Page = 0;
if (Page < 0) Page = CaseKeys.Count - 1;
DrawUI_ShowCases(player, Page);
break;
}
case "close.case.menu" : {
CuiHelper.DestroyUi(player, InterfaceBuilder.UI_CASES_MENU);
if (LocalRepositoryPlayer.ContainsKey(player)) LocalRepositoryPlayer.Remove(player);
break;
}
case "open.case" : {
LocalRepositoryPlayer[player].IsOpenedCase = true;
String CaseKey = arg.Args[1];
player.StartCoroutine(OpenCase(player, CaseKey));
break;
}
case "open.inventory" : {
DrawUI_InventoryPlayer(player);
break;
}
case "open.case.menu" : {
DrawUI_Case(player);
break;
}
case "sell.case.economic" : {
String CaseKey = arg.Args[1];
BuyAndSellCases(player, CaseKey, true);
break;
}
case "buy.case.economic" : {
String CaseKey = arg.Args[1];
BuyAndSellCases(player, CaseKey, false);
break;
}
case "inventory.take.reward" : {
if (LocalRepositoryPlayer[player].IsCooldownTake) return;
Int32 IndexReward = Int32.Parse(arg.Args[1]);
InformationPlayer.RewardPreset rewardPreset = DataPlayer[player.userID].InventoryPlayer[IndexReward];
TakeReward(player, rewardPreset);
LocalRepositoryPlayer[player].SetCooldown();
break;
}
case "inventory.page.controller" : {
Int32 Page = Int32.Parse(arg.Args[1]);
DrawUI_ShowItems_Inventory(player, Page);
break;
}
}
}
private void DrawUI_InventoryItem(BasePlayer player, InformationPlayer.RewardPreset rewardPreset, Int32 X, Int32 Y, Int32 I) {
if (rewardPreset != null) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_INVENTORY_ITEM");
if (Interface == null) return;
Interface = Interface.Replace("%PARENT_ITEM_INVENTOY%", $"ImageRareItem_{I}");
Interface = Interface.Replace("%OFFSET_MIN%", $"{-506.467 + (X * 102)} {113.333 - (Y * 110)}");
Interface = Interface.Replace("%OFFSET_MAX%", $"{-411.133 + (X * 102)} {216.667 - (Y * 110)}");
Interface = Interface.Replace("%BACKGROUND_RARE%", ImageUi.GetImage(ImageUi.GetRareImage(rewardPreset.VisualRare)));
Interface = Interface.Replace("%TITLE_ITEM%", rewardPreset.Type == TypeReward.Item ? (rewardPreset.ItemSetting.DisplayName != null && !String.IsNullOrWhiteSpace(rewardPreset.ItemSetting.DisplayName)) ? rewardPreset.ItemSetting.DisplayName : GetLang("UI_ITEM_LIST_ITEM_NAME", player.UserIDString) : (rewardPreset.CommandSetting.DisplayName != null && !String.IsNullOrWhiteSpace(rewardPreset.CommandSetting.DisplayName)) ? rewardPreset.CommandSetting.DisplayName : GetLang("UI_ITEM_LIST_COMMAND_NAME", player.UserIDString));
Interface = Interface.Replace("%ITEM_AMOUNT%", rewardPreset.Type == TypeReward.Item ? rewardPreset.ItemSetting.GetAmountLabel : rewardPreset.CommandSetting.GetAmountLabel(player));
CuiHelper.AddUi(player, Interface);
if (rewardPreset.Type == TypeReward.Item && rewardPreset.ItemSetting.IsBlueprint) _interface.Item_Blueprint(player, $"ImageRareItem_{I}");
if (!String.IsNullOrWhiteSpace(rewardPreset.PNGReward)) DrawUI_ItemPNG(player, $"ImageRareItem_{I}", ImageUi.GetImage(rewardPreset.PNGReward), $"case.func inventory.take.reward {I}");
else _interface.CaseItemsShortnameOrSkinID(player, ItemManager.FindItemDefinition(rewardPreset.ItemSetting.Shortname).itemid, UInt32.Parse(rewardPreset.ItemSetting.SkinID.ToString()), $"case.func inventory.take.reward {I}", $"ImageRareItem_{I}");
}
else DrawUI_NoRare_Panel(player, "InventoryItemPanel", "0.5 0.5", "0.5 0.5", $"{-506.467 + (X * 102)} {113.333 - (Y * 110)}", $"{-411.133 + (X * 102)} {216.667 - (Y * 110)}");
}
private void GiftDefaultCase(UInt64 playerID) {
if (!DataPlayerTakeGiftCase.ContainsKey(playerID)) DataPlayerTakeGiftCase.Add(playerID, new List<String>());
foreach (Configuration.DefaultCasePlayer defaultCasePlayer in config.DefaultCasePlayers) {
String CaseKey = defaultCasePlayer.CaseKey;
if (!CaseKeys.Contains(CaseKey)) continue;
if (DataPlayerTakeGiftCase[playerID].Contains(CaseKey)) continue;
if (!String.IsNullOrWhiteSpace(defaultCasePlayer.Permissions) && !permission.UserHasPermission(playerID.ToString(), defaultCasePlayer.Permissions)) continue;
DataPlayerTakeGiftCase[playerID].Add(CaseKey);
GiveCases(playerID, CaseKey, defaultCasePlayer.Count);
PrintError(LanguageEn ? $"Player {playerID} has been given case {CaseKey}" : $"Игроку {playerID} выдан кейс {CaseKey}");
}
}
private void Init() => ReadData();
private void DrawUI_BlockButton(BasePlayer player, String Parent) {
String Interface = InterfaceBuilder.GetInterface("UI_CASE_TEMPLATE_CASE_BUTTON_BLOCK");
if (Interface == null) return;
Interface = Interface.Replace("%PARENT%", Parent);
CuiHelper.AddUi(player, Interface);
}
private String GetRankName(String Key) {
String Rank = String.Empty;
if (!IQRankSystem) return Rank;
return (String)IQRankSystem?.Call("API_GET_RANK_NAME", Key);
}
private void RemoveBalance(UInt64 userID, Int32 Balance) {
if (IQEconomic != null) IQEconomic?.Call("API_REMOVE_BALANCE", userID, Balance);
else if (Economics != null) Economics?.Call("Withdraw", userID, Convert.ToDouble(Balance));
else if (ServerRewards != null) ServerRewards?.Call("TakePoints", userID, Balance);
}
private void SearchCaseLootable(BasePlayer player, String ShortPrefabName) {
if (!config.DropCasesList.ContainsKey(ShortPrefabName)) return;
foreach (Configuration.DropCases dropCases in config.DropCasesList[ShortPrefabName]) {
if (String.IsNullOrWhiteSpace(dropCases.Permissions) || permission.UserHasPermission(player.UserIDString, dropCases.Permissions)) {
if (GetRandomDrop(dropCases.Rare)) {
GiveCases(player.userID, dropCases.CaseKey, dropCases.Count);
break;
}
}
}
}
[ConsoleCommand("case.give.all")]
private void AdminCaseCommandGiveAll(ConsoleSystem.Arg arg) {
if (!FullInit) return;
BasePlayer player = arg.Player();
if(player != null) if (!player.IsAdmin) return;
if (!arg.HasArgs(2)) return;
String CaseKey = arg.GetString(0);
if (String.IsNullOrWhiteSpace(CaseKey) || !CaseKeys.Contains(CaseKey)) {
PrintWarning(LanguageEn ? "Case with such key does not exist" : "Кейса с таким ключем не существует");
return;
}
Int32 Amount = arg.GetInt(1, -1);
if (Amount == -1) {
PrintWarning(LanguageEn ? "The second argument is not a number!" : "Второй аргумент не является числом!");
return;
}
foreach (BasePlayer playerList in BasePlayer.activePlayerList) GiveCases(playerList.userID, CaseKey, Amount);
Puts(LanguageEn ? $"All players have been given a {CaseKey} case in the amount of {Amount}" : $"Всем игрокам выдан кейс {CaseKey} в количестве {Amount}");
}
void API_REMOVE_CASE(UInt64 userID, String CaseKey, Int32 Amount) => RemoveCases(userID, CaseKey, Amount);
private IEnumerator OpenCase(BasePlayer player, String CaseKey) {
if (!RemoveCases(player.userID, CaseKey)) yield break;
DrawUI_UpdateLabels(player, CaseKey);
Configuration.CasesPreset Case = config.CasesPresets[CaseKey];
Configuration.CasesPreset.RewardPreset RandomReward = Case.GetRandomReward();
RunEffect(player, "assets/prefabs/npc/autoturret/effects/reload.prefab");
yield return CoroutineEx.waitForSeconds(1.5f);
List<Int32> VisualRandomIndexes = new List<Int32>();
List<Configuration.CasesPreset.RewardPreset> SortedRewardsCase = Case.RewardPresets.OrderByDescending(x => x.VisualRare).ToList();
for (Int32 Index = 0; Index < SortedRewardsCase.Count; Index++) {
Configuration.CasesPreset.RewardPreset Reward = SortedRewardsCase[Index];
if (Reward != RandomReward) VisualRandomIndexes.Add(Index);
}
Int32 VisualRandomCount = VisualRandomIndexes.Count;
for (Int32 RandomIndex = 0; RandomIndex < VisualRandomCount; RandomIndex++) {
RunEffect(player, "assets/prefabs/npc/autoturret/effects/targetacquired.prefab");
Int32 VisualIndex = VisualRandomIndexes.GetRandom();
DrawUI_NoRare_Panel(player, $"RARE_{VisualIndex}", "0 0", "1 1", "0 0", "0 0");
VisualRandomIndexes.Remove(VisualIndex);
yield return CoroutineEx.waitForSeconds(0.6f);
}
RunEffect(player, "assets/prefabs/misc/casino/slotmachine/effects/payout_jackpot.prefab");
yield return CoroutineEx.waitForSeconds(0.6f);
DrawUI_ShowItems(player, CaseKey);
LocalRepositoryPlayer[player].IsOpenedCase = false;
if (!DataPlayer[player.userID].SwitchTakeInventory) GiveReward(player, DataPlayer[player.userID].GenericRewardPreset(RandomReward));
else MoveToInventory(player, RandomReward);
Log(LanguageEn ? $"Player {player.displayName} ({player.userID}) opened case {CaseKey} and received:" + $"\nType: {RandomReward.Type}" + $"\nItem Information:" + $"\nName - {RandomReward.ItemSetting.DisplayName}" + $"\nShortname - {RandomReward.ItemSetting.Shortname}" + $"\nSkinID - {RandomReward.ItemSett
// ... [Code preview truncated due to length. Full source in attached file] ...