C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//Requires: Kits
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Custom Auto Kits", "Absolut/Arainrr", "1.2.5", ResourceId = 41234154)]
[Description("Automatic kits by permission")]
public class CustomAutoKits : RustPlugin
{
[PluginReference] private readonly Plugin EventManager, Kits;
private readonly Dictionary<ulong, Hash<string, float>> kitCooldown =
new Dictionary<ulong, Hash<string, float>>();
private void Init()
{
LoadData();
cmd.AddChatCommand(configData.chatS.command, this, nameof(CmdChooseKit));
}
private void OnServerInitialized()
{
foreach (var autoKit in configData.autoKits)
{
if (!permission.PermissionExists(autoKit.permission, this))
permission.RegisterPermission(autoKit.permission, this);
foreach (var kitS in autoKit.kits)
if (!IsKit(kitS.kitName))
PrintError($"'{kitS.kitName}' kit does not exist");
}
foreach (var player in BasePlayer.allPlayerList)
storedData.players.Add(player.userID);
}
private void OnServerSave()
{
timer.Once(UnityEngine.Random.Range(0f, 60f), SaveData);
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
DestroyUI(player);
SaveData();
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null || !player.userID.IsSteamId()) return;
if (!storedData.players.Add(player.userID)) return;
OnPlayerRespawned(player);
}
private void OnPlayerRespawned(BasePlayer player)
{
var isPlaying = EventManager?.CallHook("isPlaying", player);
if (isPlaying is bool && (bool)isPlaying) return;
var playerData = GetPlayerData(player.userID, true);
if (!playerData.enabled) return;
var kitName = GetSelectedKit(player, playerData);
if (string.IsNullOrEmpty(kitName)) return;
if (configData.emptyInventory) player.inventory.Strip();
GiveKit(player, kitName);
Hash<string, float> cooldowns;
if (kitCooldown.TryGetValue(player.userID, out cooldowns)) cooldowns[kitName] = Time.realtimeSinceStartup;
else kitCooldown.Add(player.userID, new Hash<string, float> { { kitName, Time.realtimeSinceStartup } });
}
#region Methods
private string GetSelectedKit(BasePlayer player, StoredData.PlayerData playerData)
{
string kitName;
ConfigData.KitS kitS;
var availableKits = GetAvailableKits(player);
if (!availableKits.Any()) return null;
if (!string.IsNullOrEmpty(playerData.selectedKit))
{
var found = availableKits.FirstOrDefault(x => x.kitName == playerData.selectedKit);
if (found != null)
{
kitS = found;
}
else
{
playerData.selectedKit = null;
kitS = GetDefaultKit(availableKits);
}
}
else
{
kitS = GetDefaultKit(availableKits);
}
if (kitS == null) return null;
kitName = kitS.kitName;
Hash<string, float> cooldowns;
if (kitS.cooldown > 0 && kitCooldown.TryGetValue(player.userID, out cooldowns))
{
float lastUse;
if (cooldowns.TryGetValue(kitName, out lastUse) && Time.realtimeSinceStartup - lastUse < kitS.cooldown)
return kitS.cooldownKit;
}
return kitName;
}
private static ConfigData.KitS GetDefaultKit(IEnumerable<ConfigData.KitS> availableKits)
{
return availableKits.OrderByDescending(x => x.priority).First();
}
private IEnumerable<ConfigData.KitS> GetAvailableKits(BasePlayer player)
{
return from entry in configData.autoKits
where permission.UserHasPermission(player.UserIDString, entry.permission)
from kitS in entry.kits
where IsKit(kitS.kitName)
select kitS;
}
private bool IsKit(string kitName)
{
return (bool)(Kits.Call("isKit", kitName) ?? true);
}
private void GiveKit(BasePlayer player, string kitName)
{
Kits.Call("GiveKit", player, kitName);
}
private StoredData.PlayerData GetPlayerData(ulong playerID, bool readOnly = false)
{
StoredData.PlayerData playerData;
if (!storedData.playerPrefs.TryGetValue(playerID, out playerData))
{
playerData = new StoredData.PlayerData { enabled = true };
if (readOnly) return playerData;
storedData.playerPrefs.Add(playerID, playerData);
}
return playerData;
}
#endregion Methods
#region Commands
private void CmdChooseKit(BasePlayer player, string command, string[] args)
{
var availableKits = GetAvailableKits(player);
if (!availableKits.Any())
{
Print(player, Lang("NoAvailableKits", player.UserIDString));
return;
}
CreateMainUI(player);
}
[ConsoleCommand("CustomAutoKitsUI")]
private void CCmdCustomAutoKitsUI(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player == null) return;
var playerData = GetPlayerData(player.userID);
switch (arg.Args[0].ToLower())
{
case "toggle":
playerData.enabled = !playerData.enabled;
UpdateMenuUI(player, playerData);
return;
case "choose":
var kitName = arg.Args[1];
playerData.selectedKit = playerData.selectedKit == kitName ? null : kitName;
UpdateMenuUI(player, playerData);
return;
}
}
#endregion Commands
#region UI
private const string UINAME_MAIN = "CustomAutoKitsUI_Main";
private const string UINAME_MENU = "CustomAutoKitsUI_Menu";
private void CreateMainUI(BasePlayer player)
{
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0" },
RectTransform =
{AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-210 -180", OffsetMax = "210 220"},
CursorEnabled = true
}, "Hud", UINAME_MAIN);
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0.6" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
}, UINAME_MAIN);
var titlePanel = container.Add(new CuiPanel
{
Image = { Color = "0.42 0.88 0.88 1" },
RectTransform = { AnchorMin = "0 0.902", AnchorMax = "0.995 1" }
}, UINAME_MAIN);
container.Add(new CuiElement
{
Parent = titlePanel,
Components =
{
new CuiTextComponent
{
Text = Lang("Title", player.UserIDString), FontSize = 20, Align = TextAnchor.MiddleCenter,
Color = "1 0 0 1"
},
new CuiOutlineComponent {Distance = "0.5 0.5", Color = "1 1 1 1"},
new CuiRectTransformComponent {AnchorMin = "0.2 0", AnchorMax = "0.8 1"}
}
});
container.Add(new CuiButton
{
Button = { Color = "0.95 0.1 0.1 0.95", Close = UINAME_MAIN },
Text = { Text = "X", Align = TextAnchor.MiddleCenter, Color = "0 0 0 1", FontSize = 22 },
RectTransform = { AnchorMin = "0.885 0.05", AnchorMax = "0.995 0.95" }
}, titlePanel);
CuiHelper.DestroyUi(player, UINAME_MAIN);
CuiHelper.AddUi(player, container);
var playerData = GetPlayerData(player.userID, true);
UpdateMenuUI(player, playerData);
}
private void UpdateMenuUI(BasePlayer player, StoredData.PlayerData playerData)
{
if (player == null) return;
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.4" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.898" }
}, UINAME_MAIN, UINAME_MENU);
var selectedKitName = GetSelectedKit(player, playerData);
var availableKits = GetAvailableKits(player);
var i = 0;
var spacing = 1f / 10;
var anchors = GetEntryAnchors(i++, spacing);
CreateEntry(ref container, $"CustomAutoKitsUI Toggle", Lang("Status", player.UserIDString),
playerData.enabled ? Lang("Enabled", player.UserIDString) : Lang("Disabled", player.UserIDString),
$"0 {anchors[0]}", $"1 {anchors[1]}");
foreach (var kitS in availableKits)
{
var kitName = kitS.kitName;
anchors = GetEntryAnchors(i++, spacing);
CreateEntry(ref container, $"CustomAutoKitsUI Choose {kitName}", kitName,
selectedKitName == kitName
? Lang("Selected", player.UserIDString)
: Lang("Unselected", player.UserIDString), $"0 {anchors[0]}", $"1 {anchors[1]}");
}
CuiHelper.DestroyUi(player, UINAME_MENU);
CuiHelper.AddUi(player, container);
}
private static void CreateEntry(ref CuiElementContainer container, string command, string leftText,
string rightText, string anchorMin, string anchorMax)
{
var panelName = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.6" },
RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax }
}, UINAME_MENU);
container.Add(new CuiLabel
{
Text = { Color = "0 1 1 1", FontSize = 14, Align = TextAnchor.MiddleLeft, Text = leftText },
RectTransform = { AnchorMin = "0.1 0", AnchorMax = "0.795 1" }
}, panelName);
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0.7", Command = command },
Text = { Text = rightText, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FontSize = 14 },
RectTransform = { AnchorMin = "0.8 0.01", AnchorMax = "0.995 0.99" }
}, panelName);
}
private static float[] GetEntryAnchors(int i, float spacing)
{
return new[] { 1f - (i + 1) * spacing, 1f - i * spacing };
}
private static void DestroyUI(BasePlayer player)
{
CuiHelper.DestroyUi(player, UINAME_MAIN);
}
#endregion UI
#region ConfigurationFile
private ConfigData configData;
private class ConfigData
{
[JsonProperty(PropertyName = "Empty default items before give kits")]
public bool emptyInventory = true;
[JsonProperty(PropertyName = "Auto Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<AutoKit> autoKits = new List<AutoKit>
{
new AutoKit
{
permission = "customautokits.vip1",
kits = new List<KitS>
{
new KitS
{
priority = 0,
cooldown = 0,
kitName = "KitName1",
cooldownKit = "Cooldown Kit"
}
}
},
new AutoKit
{
permission = "customautokits.vip2",
kits = new List<KitS>
{
new KitS
{
priority = 1,
cooldown = 0,
kitName = "KitName2",
cooldownKit = "Cooldown Kit"
},
new KitS
{
priority = 2,
cooldown = 0,
kitName = "KitName21",
cooldownKit = "Cooldown Kit"
}
}
}
};
public class AutoKit
{
public string permission = string.Empty;
public List<KitS> kits = new List<KitS>();
}
public class KitS
{
public int priority;
public float cooldown;
public string kitName = string.Empty;
public string cooldownKit = string.Empty;
}
[JsonProperty(PropertyName = "Chat Settings")]
public ChatSettings chatS = new ChatSettings();
public class ChatSettings
{
[JsonProperty(PropertyName = "Chat Command")]
public string command = "autokit";
[JsonProperty(PropertyName = "Chat Prefix")]
public string prefix = "<color=#00FFFF>[CustomAutoKits]</color>: ";
[JsonProperty(PropertyName = "Chat SteamID Icon")]
public ulong steamIDIcon = 0;
}
[JsonProperty(PropertyName = "Version")]
public VersionNumber version = new VersionNumber(1, 2, 4);
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
configData = Config.ReadObject<ConfigData>();
if (configData == null)
LoadDefaultConfig();
else
UpdateConfigValues();
}
catch
{
PrintError("The configuration file is corrupted");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
PrintWarning("Creating a new configuration file");
configData = new ConfigData();
}
protected override void SaveConfig()
{
Config.WriteObject(configData);
}
private void UpdateConfigValues()
{
if (configData.version < Version)
{
if (configData.version <= new VersionNumber(1, 2, 4))
{
if (configData.chatS.prefix == "[CustomAutoKits]: ")
{
configData.chatS.prefix = "<color=#00FFFF>[CustomAutoKits]</color>: ";
}
}
configData.version = Version;
}
}
#endregion ConfigurationFile
#region DataFile
private StoredData storedData;
private class StoredData
{
public readonly Dictionary<ulong, PlayerData> playerPrefs = new Dictionary<ulong, PlayerData>();
public readonly HashSet<ulong> players = new HashSet<ulong>();
public class PlayerData
{
public bool enabled;
public string selectedKit;
}
}
private void LoadData()
{
try
{
storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
}
catch
{
storedData = null;
}
finally
{
if (storedData == null)
{
ClearData();
}
}
}
private void SaveData()
{
Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);
}
private void ClearData()
{
storedData = new StoredData();
SaveData();
}
private void OnNewSave(string filename)
{
storedData.players.Clear();
SaveData();
}
#endregion DataFile
#region LanguageFile
private void Print(BasePlayer player, string message)
{
Player.Message(player, message, configData.chatS.prefix, configData.chatS.steamIDIcon);
}
private string Lang(string key, string id = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, id), args);
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NoAvailableKits"] = "You don't have any available kits",
["Title"] = "Custom Auto Kits UI",
["Status"] = "Respawn kit status",
["Selected"] = "<color=#8ee700>Selected</color>",
["Unselected"] = "<color=#ce422b>X</color>",
["Enabled"] = "<color=#8ee700>Enabled</color>",
["Disabled"] = "<color=#ce422b>Disabled</color>"
}, this);
lang.RegisterMessages(new Dictionary<string, string>
{
["NoAvailableKits"] = "您没有可用的复活礼包",
["Title"] = "自定义复活礼包",
["Status"] = "复活礼包状态",
["Selected"] = "<color=#8ee700>已选择</color>",
["Unselected"] = "<color=#ce422b>未选择</color>",
["Enabled"] = "<color=#8ee700>已启用</color>",
["Disabled"] = "<color=#ce422b>已禁用</color>"
}, this, "zh-CN");
}
#endregion LanguageFile
}
}