C#:
using UnityEngine;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using System;
using Oxide.Core;
using Oxide.Core.Configuration;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core.Libraries;
using System.Collections.Generic;
namespace Oxide.Plugins {
/*ПЛАГИН БЫЛ ПОФИКШЕН С ПОМОЩЬЮ ПРОГРАММЫ СКАЧАНОЙ С https://discord.gg/dNGbxafuJn */
[Info("Case", "https://discord.gg/dNGbxafuJn", "1.0.1")]
[Description("Cases for Rust")]
class Case : RustPlugin {
#region PluginReference
[PluginReference]
Plugin ImageLibrary;
public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary.Call("GetImage", shortname, skin);
public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname, skin);
public bool AddImageData(string imageName, byte[] array, ulong imageId) => (bool)ImageLibrary?.Call("AddImageData", imageName, array, imageId);
#endregion
#region CFG
string FonPNG = "https://i.imgur.com/BVrpgZd.jpg";
string ChatPrefix = "<color=#ffe100>RUST CLUB:</color>";
int RewardHeli = 10;
int RewardBradley = 10;
int RewardAnimal = 10;
int RewardMoney = 1;
int RewardBarrel = 1;
protected override void LoadDefaultConfig() {
LoadConfigValues();
}
private void LoadConfigValues() {
GetConfig("[Оформление]", "Фон", ref FonPNG);
GetConfig("[Оформление]", "Префикс", ref ChatPrefix);
GetConfig("[Награда]", "За вертолет", ref RewardHeli);
GetConfig("[Награда]", "За танк", ref RewardBradley);
GetConfig("[Награда]", "За животное", ref RewardAnimal);
GetConfig("[Награда]", "За бочку(каждая десятая и % шанс при разбитии любой бочки)", ref RewardBarrel);
GetConfig("[Награда]", "Каждые 10 минут", ref RewardMoney);
SaveConfig();
}
private void GetConfig<T>(string menu, string Key, ref T var) {
if (Config[menu, Key] != null) {
var = (T)Convert.ChangeType(Config[menu, Key], typeof(T));
}
Config[menu, Key] = var;
}
#endregion
#region DataStorage
DataStorage DataUsers;
DynamicConfigFile DataUsersDynamic;
private List<CaseTimeData> CaseTime;
private List<CaseMoneyData> CaseMoney;
class DataStorage {
public Dictionary<ulong, UserData> Users = new Dictionary<ulong, UserData>();
public DataStorage() {
}
}
class UserData {
public string Name;
public int Time;
public int Money;
public int CaseOpen;
public bool[] IsOpen = {
false, false, false, false, false, false,
}
;
}
class CaseTimeData {
public string CaseName {
get;
set;
}
public int CaseID {
get;
set;
}
public int CaseCost {
get;
set;
}
public List<string> CaseCommand {
get;
set;
}
public List<CaseTimeItems> CaseItems {
get;
set;
}
public string CasePng {
get;
set;
}
}
class CaseTimeItems {
public string ShortName {
get;
set;
}
public string MinAmount {
get;
set;
}
public string MaxAmount {
get;
set;
}
}
class CaseMoneyData {
public string CaseName {
get;
set;
}
public int CaseID {
get;
set;
}
public int CaseCost {
get;
set;
}
public List<string> CaseCommand {
get;
set;
}
public List<CaseMoneyItems> CaseItems {
get;
set;
}
public string CasePng {
get;
set;
}
}
class CaseMoneyItems {
public string ShortName {
get;
set;
}
public string MinAmount {
get;
set;
}
public string MaxAmount {
get;
set;
}
}
void CheckData(BasePlayer player) {
if (!DataUsers.Users.ContainsKey(player.userID)) {
DataUsers.Users.Add(player.userID, new UserData() {
Name = player.displayName, Time = 0, Money = 0, CaseOpen = 0, IsOpen = {
[0]
= false, [1] = false, [2] = false, [3] = false, [4] = false, [5] = false
}
}
);
}
}
void LoadData() {
try {
DataUsers = Interface.GetMod().DataFileSystem.ReadObject<DataStorage>("Case_Users");
}
catch {
DataUsers = new DataStorage();
}
CaseTime = Interface.Oxide.DataFileSystem.ReadObject<List<CaseTimeData>>("Case_Time");
CaseMoney = Interface.Oxide.DataFileSystem.ReadObject<List<CaseMoneyData>>("Case_Money");
}
void SaveData() {
DataUsersDynamic.WriteObject(DataUsers);
}
#endregion
#region Image
string ImageFon, ImageCase;
private void AddStandartImage() {
AddImage(FonPNG, "FonPNG", 0);
foreach(var Case in CaseTime) {
AddImage(Case.CasePng, $"CaseTime{Case.CaseID}");
}
foreach (var Case in CaseMoney) {
AddImage(Case.CasePng, $"CaseMoney{Case.CaseID}");
}
}
#endregion
#region GUI
private Dictionary<ulong, bool> HasFon = new Dictionary<ulong, bool>();
double pos;
int Hours, Min;
[ConsoleCommand("caseui")]
private void CreateGUI(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
CuiHelper.DestroyUi(player, "Case");
if (!HasFon.ContainsKey(player.userID)) {
AddFon(player);
HasFon.Add(player.userID, true);
}
CuiElementContainer Container = new CuiElementContainer();
Container.Add(new CuiElement {
Name = "Case", Parent = "Hud", Components = {
new CuiRawImageComponent {
Sprite = "assets/content/textures/generic/fulltransparent.tga"
}
, new CuiRectTransformComponent {
AnchorMin = "0.143 0.139", AnchorMax = "0.857 0.861"
}
}
}
);
pos = 0.425f - (CaseTime.Count() * 0.1 + (CaseTime.Count() - 1) * 0.025) / 2;
foreach (var Case in CaseTime) {
ImageCase = GetImage($"CaseTime{Case.CaseID}");
CreateImage(Container, $"CaseTime{Case.CaseID}", $"Case", ImageCase, $"{pos} 0.65", $"{pos + 0.125} 0.90");
pos += 0.15f;
if(DataUsers.Users[player.userID].IsOpen[Case.CaseID]) {
CreatePanel(Container, $"CaseTimeOpen{Case.CaseID}", $"CaseTime{Case.CaseID}", "0 0 0 0.7", "0 0", "0.994 0.997");
CreateTitle(Container, $"CaseTimeOpenTitle{Case.CaseID}", $"CaseTimeOpen{Case.CaseID}", $"Уже взят", TextAnchor.LowerCenter, "0 0.01", "1 1");
}
Hours = (Case.CaseCost - DataUsers.Users[player.userID].Time) / 60;
Min = (Case.CaseCost - DataUsers.Users[player.userID].Time) % 60;
if (DataUsers.Users[player.userID].Time < Case.CaseCost) {
CreatePanel(Container, $"CaseTimeCost{Case.CaseID}", $"CaseTime{Case.CaseID}", "0 0 0 0.7", "0 0", "0.994 0.997");
if(Hours > 0 && Min > 0) CreateTitle(Container, $"CaseTimeCostTitle{Case.CaseID}", $"CaseTimeCost{Case.CaseID}", $"<size=12>{Format(Hours, "часов", "часа", "час")} {Format(Min, "минут", "минуты", "минуту")}</size>", TextAnchor.LowerCenter, "0 0.01", "1 1");
if (Hours > 0 && Min == 0) CreateTitle(Container, $"CaseTimeCostTitle{Case.CaseID}", $"CaseTimeCost{Case.CaseID}", $"<size=12>{Format(Hours, "часов", "часа", "час")}</size>", TextAnchor.LowerCenter, "0 0.01", "1 1");
if (Hours == 0 && Min > 0) CreateTitle(Container, $"CaseTimeCostTitle{Case.CaseID}", $"CaseTimeCost{Case.CaseID}", $"<size=12>{Format(Min, "минут", "минуты", "минуту")}</size>", TextAnchor.LowerCenter, "0 0.01", "1 1");
}
if(DataUsers.Users[player.userID].Time >= Case.CaseCost && !(DataUsers.Users[player.userID].IsOpen[Case.CaseID])) CreateButton(Container, $"CaseTimeButton{Case.CaseID}", $"CaseTime{Case.CaseID}", "0 0 0 0", $"caseget CaseTime {Case.CaseID}", "0 0", "1 1", "");
}
pos = 0.425f - (CaseTime.Count() * 0.1 + (CaseTime.Count() - 1) * 0.025) / 2;
foreach (var Case in CaseMoney) {
ImageCase = GetImage($"CaseMoney{Case.CaseID}");
CreateImage(Container, $"CaseMoney{Case.CaseID}", $"Case", ImageCase, $"{pos} 0.35", $"{pos + 0.125} 0.60");
CreateTitle(Container, $"CaseMoneyCostTitle{Case.CaseID}", $"CaseMoney{Case.CaseID}", $"{Case.CaseCost}$", TextAnchor.MiddleCenter, "0.70 0.80", "0.96 0.97");
pos += 0.15f;
if (DataUsers.Users[player.userID].Money < Case.CaseCost) {
CreatePanel(Container, $"CaseMoneyCost{Case.CaseID}", $"CaseMoney{Case.CaseID}", "0 0 0 0.7", "0 0", "0.994 0.997");
CreateTitle(Container, $"CaseMoneyCostTitle{Case.CaseID}", $"CaseMoneyCost{Case.CaseID}", $"<size=10>Не хватает: {Format((Case.CaseCost - DataUsers.Users[player.userID].Money), "<size=10>монет</size>", "<size=10>монеты</size>", "<size=10>монету</size>")}</size>", TextAnchor.LowerCenter, "0 0", "1 1");
}
if (DataUsers.Users[player.userID].Money >= Case.CaseCost) CreateButton(Container, $"CaseMoneyButton{Case.CaseID}", $"CaseMoney{Case.CaseID}", "0 0 0 0", $"caseget CaseMoney {Case.CaseID}", "0 0", "1 1", "");
}
Hours = DataUsers.Users[player.userID].Time / 60;
Min = DataUsers.Users[player.userID].Time % 60;
CreateTitle(Container, "CaseFonTitle", "Case", "<size=20>Время проведенное на сервере: \nМонет: \nКейсов открыто: \n</size>", TextAnchor.UpperLeft, "0.06 0.02", "0.6 0.25");
if (Hours > 0) {
CreateTitle(Container, "CaseFonTitleValue", "Case", $"<size=20><color=#ECBE13>{Format(Hours, "часов", "часа", "час")} {Format(Min, "минут", "минуты", "минуту")}\n{DataUsers.Users[player.userID].Money}\n{DataUsers.Users[player.userID].CaseOpen}</color></size>", TextAnchor.UpperRight, "0.06 0.02", "0.6 0.25");
}
else {
CreateTitle(Container, "CaseFonTitleValue", "Case", $"<size=20><color=#ECBE13>{Format(Min, "минут", "минуты", "минуту")}\n{DataUsers.Users[player.userID].Money}\n{DataUsers.Users[player.userID].CaseOpen}</color></size>", TextAnchor.UpperRight, "0.06 0.02", "0.6 0.25");
}
CreateButton(Container, "ButtonClose", "Case", "0.91 0.72 0.08 1", "caseclosefull", "0.635 0.08", "0.94 0.25", "<size=24>ЗАКРЫТЬ</size>");
CuiHelper.AddUi(player, Container);
}
private void AddFon(BasePlayer player) {
ImageFon = GetImage("FonPNG", 0);
CuiElementContainer Container = new CuiElementContainer();
Container.Add(new CuiElement {
Name = "CaseFon", Parent = "Hud", Components = {
new CuiRawImageComponent {
Png = ImageFon
}
, new CuiRectTransformComponent {
AnchorMin = "0.143 0.139", AnchorMax = "0.857 0.861"
}
, new CuiNeedsCursorComponent()
}
}
);
CuiHelper.AddUi(player, Container);
}
[ChatCommand("case")]
private void ChatStats(BasePlayer player) {
player.SendConsoleCommand("caseui");
}
[ChatCommand("caseclosefull")]
private void DestroyFullGUI(BasePlayer player) {
CuiHelper.DestroyUi(player, "Case");
CuiHelper.DestroyUi(player, "CaseFon");
HasFon.Remove(player.userID);
}
[ChatCommand("caseclose")]
private void DestroyGUI(BasePlayer player) {
CuiHelper.DestroyUi(player, "Case");
}
[ConsoleCommand("caseclose")]
private void CmdDestroyGui(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
CuiHelper.DestroyUi(player, "Case");
}
[ConsoleCommand("caseclosefull")]
private void CmdDestroyFullGui(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
CuiHelper.DestroyUi(player, "Case");
CuiHelper.DestroyUi(player, "CaseFon");
HasFon.Remove(player.userID);
}
#endregion
#region GUI Template
private void CreatePanel(CuiElementContainer Container, string Name, string Parent, string Color, string AnchorMin, string AnchorMax) {
Container.Add(new CuiElement {
Name = Name, Parent = Parent, Components = {
new CuiImageComponent {
Color = Color
}
, new CuiRectTransformComponent {
AnchorMin = AnchorMin, AnchorMax = AnchorMax
}
}
}
);
}
private void CreateImage(CuiElementContainer Container, string Name, string Parent, string Png, string AnchorMin, string AnchorMax) {
Container.Add(new CuiElement {
Name = Name, Parent = Parent, Components = {
new CuiRawImageComponent {
Png = Png
}
, new CuiRectTransformComponent {
AnchorMin = AnchorMin, AnchorMax = AnchorMax
}
}
}
);
}
private void CreateButton(CuiElementContainer Container, string Name, string Parent, string Color, string Command, string AnchorMin, string AnchorMax, string Text) {
Container.Add(new CuiButton {
Button = {
Color = Color, Command = Command
}
, RectTransform = {
AnchorMin = AnchorMin, AnchorMax = AnchorMax
}
, Text = {
Text = Text, Align = TextAnchor.MiddleCenter
}
}
, Parent, Name);
}
private void CreateTitle(CuiElementContainer Container, string Name, string Parent, string Text, TextAnchor Align, string AnchorMin, string AnchorMax) {
Container.Add(new CuiElement {
Name = Name, Parent = Parent, Components = {
new CuiTextComponent {
Text = Text, Align = Align
}
, new CuiRectTransformComponent {
AnchorMin = AnchorMin, AnchorMax = AnchorMax
}
}
}
);
}
#endregion
#region Case
[ConsoleCommand("caseget")]
private void CaseGet(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (!arg.HasArgs()) return;
var CaseType = arg.Args[0];
var ID = Convert.ToInt32(arg.Args[1]);
switch(CaseType) {
case "CaseTime" : {
if(!CaseTime.Exists(x => x.CaseID == ID)) return;
var CaseID = CaseTime.First(x => x.CaseID == ID);
var LootCount = CaseID.CaseItems.Count();
if ((player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count) < LootCount) {
SendReply(player, $"{ChatPrefix} Не хватает места в инвентаре");
return;
}
if(DataUsers.Users[player.userID].Time < CaseID.CaseCost) {
SendReply(player, $"{ChatPrefix} Не хватает наигранного времени");
return;
}
else if(DataUsers.Users[player.userID].IsOpen[CaseID.CaseID]) {
SendReply(player, $"{ChatPrefix} Кейс уже был открыт");
return;
}
else {
DataUsers.Users[player.userID].IsOpen[CaseID.CaseID] = true;
DataUsers.Users[player.userID].CaseOpen++;
foreach (var Item in CaseID.CaseItems) {
Item item = ItemManager.CreateByName(Item.ShortName, UnityEngine.Random.Range(Convert.ToInt32(Item.MinAmount), Convert.ToInt32(Item.MaxAmount)));
item.MoveToContainer(player.inventory.containerMain, -1, false);
}
foreach (var command in CaseID.CaseCommand) {
if (command == "Test") break;
rust.RunServerCommand(String.Format(command, player.userID));
LogToFile("Case", $"Игрок {player.displayName} получил привилегию {command}", this);
}
player.SendConsoleCommand("caseui");
}
break;
}
case "CaseMoney" : {
if (!CaseMoney.Exists(x => x.CaseID == ID)) return;
var CaseID = CaseMoney.First(x => x.CaseID == ID);
var LootCount = CaseID.CaseItems.Count();
if ((player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count) < LootCount) {
SendReply(player, $"{ChatPrefix} Не хватает места в инвентаре");
return;
}
if (DataUsers.Users[player.userID].Money < CaseID.CaseCost) {
SendReply(player, $"{ChatPrefix} Не хватает монет");
return;
}
else {
DataUsers.Users[player.userID].Money = DataUsers.Users[player.userID].Money - CaseID.CaseCost;
DataUsers.Users[player.userID].CaseOpen++;
foreach (var Item in CaseID.CaseItems) {
Item item = ItemManager.CreateByName(Item.ShortName, UnityEngine.Random.Range(Convert.ToInt32(Item.MinAmount), Convert.ToInt32(Item.MaxAmount)));
item.MoveToContainer(player.inventory.containerMain, -1, false);
}
foreach (var command in CaseID.CaseCommand) {
if (command == "Test") break;
rust.RunServerCommand(String.Format(command, player.userID));
LogToFile("Case", $"Игрок {player.displayName} получил привилегию {command}", this);
}
player.SendConsoleCommand("caseui");
}
break;
}
}
}
#endregion
#region Hooks
void OnServerInitialized() {
LoadDefaultConfig();
DataUsersDynamic = Interface.Oxide.DataFileSystem.GetFile("Case_Users");
LoadData();
AddStandartImage();
RewardTime();
for(int i = 0; i<BasePlayer.activePlayerList.Count; i++) OnPlayerConnected(BasePlayer.activePlayerList[i]);
}
void OnPlayerConnected(BasePlayer player) {
CheckData(player);
DataUsers.Users[player.userID].Name = player.displayName.ToString();
}
void OnPluginLoaded(Plugin name) {
foreach (BasePlayer player in BasePlayer.activePlayerList) {
CheckData(player);
DataUsers.Users[player.userID].Name = player.displayName.ToString();
}
}
void Unload() {
foreach(BasePlayer player in BasePlayer.activePlayerList) {
DestroyFullGUI(player);
}
SaveData();
}
#endregion
#region Staff
private Dictionary<ulong, BasePlayer> LastHeli = new Dictionary<ulong, BasePlayer>();
private Dictionary<ulong, BasePlayer> LastBradley = new Dictionary<ulong, BasePlayer>();
private Dictionary<BasePlayer, int> Barrels = new Dictionary<BasePlayer, int>();
void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (entity is BaseHelicopter && info.InitiatorPlayer != null) LastHeli[entity.net.ID.Value] = info.InitiatorPlayer;
if (entity is BradleyAPC && info.InitiatorPlayer != null) LastBradley[entity.net.ID.Value] = info.InitiatorPlayer;
}
void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
if (entity == null) return;
if (entity.name.Contains("assets/prefabs/plants/")) return;
if (entity.name.Contains("assets/bundled/prefabs/radtown/oil_barrel.prefab") || entity.name.Contains("assets/bundled/prefabs/radtown/loot_barrel_1.prefab") || entity.name.Contains("assets/bundled/prefabs/autospawn/resource/loot/loot-barrel-1.prefab") || entity.name.Contains("assets/bundled/prefabs/autospawn/resource/loot/loot-barrel-2.prefab") || entity.name.Contains("assets/bundled/prefabs/radtown/loot_barrel_2.prefab") && info.Initiator is BasePlayer) {
var attacker = info.InitiatorPlayer;
int RandomBarrel = UnityEngine.Random.Range(1, 100);
if(RandomBarrel > 94) {
DataUsers.Users[attacker.userID].Money += RewardBarrel;
}
if(!Barrels.ContainsKey(attacker)) {
Barrels.Add(attacker, 1);
}
else {
Barrels[attacker]++;
}
if(Barrels[attacker] == 10) {
DataUsers.Users[attacker.userID].Money += RewardBarrel;
Barrels[attacker] = 0;
}
return;
}
if (entity is BaseHelicopter) {
if (LastHeli.ContainsKey(entity.net.ID.Value)) {
var attacker = LastHeli[entity.net.ID.Value];
DataUsers.Users[attacker.userID].Money = DataUsers.Users[attacker.userID].Money + RewardHeli;
return;
}
}
if (entity is BradleyAPC) {
if (LastBradley.ContainsKey(entity.net.ID.Value)) {
var attacker = LastBradley[entity.net.ID.Value];
DataUsers.Users[attacker.userID].Money = DataUsers.Users[attacker.userID].Money + RewardBradley;
return;
}
}
if (entity.name.Contains("assets/rust.ai/agents/") && info.Initiator is BasePlayer) {
var attacker = info.InitiatorPlayer;
DataUsers.Users[attacker.userID].Money = DataUsers.Users[attacker.userID].Money + RewardAnimal;
return;
}
}
int iMoney = 0;
private void RewardTime() {
timer.Repeat(60, 0, () => {
iMoney++;
foreach (BasePlayer player in BasePlayer.activePlayerList) {
if (iMoney > 9) {
DataUsers.Users[player.userID].Money++;
}
if (!IsPlayerAfk(player)) {
DataUsers.Users[player.userID].Time++;
}
}
if (iMoney > 9) {
iMoney = 0;
Server.Broadcast($"{ChatPrefix} Каждый активный игрок получил {Format(RewardMoney, "\nмонет", "\nмонеты", "\nмонету")}");
}
SaveData();
}
);
}
private static string Format(int 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}";
if (units >= 10) return $"{units} {form1}";
return $"{units} {form3}";
}
private Hash<ulong, Vector3> LastPosition = new Hash<ulong, Vector3>();
private bool IsPlayerAfk(BasePlayer player) {
if (player == null) return true;
var last = LastPosition[player.userID];
var current = player.transform.position;
if (last.x.Equals(current.x)) return true;
LastPosition[player.userID] = current;
return false;
}
#endregion
}
}