Иконка ресурса

FREE StaticLootables : 2.10.4 2.10.4

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using Facepunch;
using UnityEngine;
namespace Oxide.Plugins;
[Info("StaticLootables", "Raul-Sorin Sorban", "2.10.4")]
[Description("Loot containers that aren't normally supposed to be looted.")]
public class StaticLootables : RustPlugin {
    public static StaticLootables Instance {
        get;
        private set;
    }
    public System.Random Randomizer {
        get;
        set;
    }
    = new();
    public System.Random GetSeededRandomizer(int seed) {
        return new System.Random(seed);
    }
    public Dictionary<string, string> PanelTypes {
        get;
        set;
    }
    = new() {
        ["generic"]
        = "Generic", ["genericsmall"] = "Generic - Small", ["generic_large"] = "Generic - Large", ["generic_resizable"] = "Generic - Resizable", ["locker"] = "Locker", ["lantern"] = "Lantern", ["mailboxcontents"] = "Mailbox Contents", ["photoframe"] = "Photo Frame", ["reclaim"] = "Reclaim", ["skulltrophy"] = "Skull Trophy", ["toolcupboard"] = "Tool Cupboard"
    }
    ;
    public List<string> PanelTypesList {
        get;
        set;
    }
    = new();
#region Permissions
    public const string AdminPerm = "staticlootables.admin";
    public const string EditorPerm = "staticlootables.editor";
    public void RegisterPermissions() {
        permission.RegisterPermission(AdminPerm, this);
        permission.RegisterPermission(EditorPerm, this);
    }
#endregion
#region Plugins
    [PluginReference]
    Plugin ImageLibrary;
    [PluginReference]
    Plugin QuickSort;
    [PluginReference]
    Plugin ZoneManager;
    [PluginReference]
    Plugin LootablesExt;
    public void RefreshPlugins() {
        if (ImageLibrary == null || !ImageLibrary.IsLoaded) {
            ImageLibrary = plugins.Find("ImageLibrary");
            ImageLibrary?.Load();
        }
        if (QuickSort == null || !QuickSort.IsLoaded) {
            QuickSort = plugins.Find("QuickSort");
            QuickSort?.Load();
        }
        if (ZoneManager == null || !ZoneManager.IsLoaded) {
            ZoneManager = plugins.Find("ZoneManager");
            ZoneManager?.Load();
        }
        if (LootablesExt == null || !LootablesExt.IsLoaded) {
            LootablesExt = plugins.Find("LootablesExt");
            LootablesExt?.Load();
        }
    }
#endregion
#region CUI
    public const string CUIInteractionName = "stlootable";
    public const string CUIEditorInteractionName = "stlootableeditorinteraction";
    public const string CUIEditorName = "stlootableeditor";
    public const string CUICodeLockInputName = "stlootableclin";
    public const string CUIPinAppendCommand = "staticlootables.pinappend";
    public const string CUIPinApplyCommand = "staticlootables.pinapply";
    public const string CUIPinUndoCommand = "staticlootables.pinundo";
    public const string DamageColor = "1 0.3 0.3 0.8";
    public const string HackingColor = "0.5 0.8 0.3 0.8";
    public Dictionary<BasePlayer, PlayerInteraction?> CUIPlayers {
        get;
        set;
    }
    = new(800);
    public Dictionary<BasePlayer, TimeSince> TimedPlayers {
        get;
        set;
    }
    = new(800);
    public Dictionary<BasePlayer, Vector3> PositionCache {
        get;
        set;
    }
    = new(800);
    public Dictionary<BasePlayer, string> PinCache {
        get;
        set;
    }
    = new(800);
    public Dictionary<BasePlayer, RootData.Lootable> LootingPlayers {
        get;
        set;
    }
    = new(800);
    public List<BasePlayer> DrawnUI {
        get;
        set;
    }
    = new();
    public const int ProcessorCount = 1;
    public struct PlayerInteraction {
        public RootConfig.Interaction Interaction {
            get;
            set;
        }
        public RootLock Lock {
            get;
            set;
        }
        public RootHack Hack {
            get;
            set;
        }
        public RootData.Lootable Lootable {
            get;
            set;
        }
        public bool IsProcessingCommand {
            get;
            set;
        }
        public bool IsLoadingTimer {
            get;
            set;
        }
        public DateTime Timer {
            get;
            set;
        }
        public float TimerTime => (float)(DateTime.Now - Timer).TotalSeconds;
    }
    public void DrawInteraction(BasePlayer player, RootConfig.Interaction interaction, RootConfig.LootableDefinition definition, RootData.Lootable lootable, bool transition = true, bool enableDot = true, bool reset = true) {
        // UndrawInteraction(player, reset);
        var container = new CuiElementContainer();
        var background = container.Add(new CuiPanel {
            Image = {
                Color = $"0 0 0 0"
            }
            , RectTransform = {
                AnchorMin = "0.36 0.36", AnchorMax = "0.64 0.738"
            }
            , CursorEnabled = false
        }
        , "Hud", CUIInteractionName, CUIInteractionName);
        var offset = "0 -10";
        var fade = transition ? 0.3f : 0f;
        var @lock = lootable != null && lootable.Lock != null ? lootable.Lock : null;
        var hack = lootable != null && lootable.Hack != null ? lootable.Hack : null;
        var i = default(PlayerInteraction?);
        if (!CUIPlayers.ContainsKey(player)) CUIPlayers.Add(player, i = new PlayerInteraction {
            Interaction = interaction, Lock = @lock, Lootable = lootable
        }
        );
        else i = CUIPlayers[player];
        if (i == null) return;
        if (enableDot) container.Add(new CuiElement {
            Parent = background, FadeOut = fade, Components = {
                Death.GetRawImage(Config.Urls.DotUrl, fade : fade), new CuiRectTransformComponent {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = offset, OffsetMax = offset
                }
            }
        }
        );
        if (Config.ShadowOpacity != 0f) container.Add(new CuiElement {
            Parent = background, FadeOut = fade, Components = {
                Death.GetRawImage(Config.Urls.ShadowUrl, color : $"1 1 1 {Config.ShadowOpacity}", fade : fade), new CuiRectTransformComponent {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = offset, OffsetMax = offset
                }
            }
        }
        );
        container.Add(new CuiElement {
            Parent = background, FadeOut = fade, Components = {
                Death.GetRawImage(i.Value.IsProcessingCommand ? Config.Urls.LoadingUrl : lootable != null && lootable.IsBusy(player) ? Config.Urls.BusyUrl : (@lock == null ? (hack == null ? interaction.Icon : hack.IsHacking ? Config.Urls.HackingUrl : Config.Urls.HackUrl) : Config.Urls.LockUrl), fade : fade), new CuiRectTransformComponent {
                    AnchorMin = "0.46 0.53", AnchorMax = "0.54 0.63", OffsetMin = offset, OffsetMax = offset
                }
            }
        }
        );
        container.Add(new CuiLabel {
            Text = {
                Text = $"{Config.InteractionPrefix}<b>{(i.Value.IsProcessingCommand ? Config.CommandName : lootable != null && lootable.IsBusy(player) ? $" {
                    Config.BusyName
                }
                " : (@lock == null ? hack == null ? interaction.Text : hack.IsHacking ? Config.HackingName : Config.HackName : Config.LockName))}{(hack == null || @lock != null || (hack?.IsHacking).GetValueOrDefault() ? string.Empty : $" {
                    Config.HackingPrefix
                }
                ")}</b>".ToUpper(), FadeIn = fade, FontSize = 13, Font = "robotocondensed-regular.ttf", Align = TextAnchor.LowerCenter
            }
            , RectTransform = {
                AnchorMin = $"0 0.4275", AnchorMax = $"1 1"
            }
        }
        , background);
        if (lootable != null) {
            if (lootable.IsLocked() && definition != null && definition.Lock != null) {
                var value = lootable.Lock.Health;
                var total = definition.Lock.Health * Config.LootableHealthMultiplier;
                var count = lootable.Contents.Count;
                DrawInteractionBar(background, container, value, total, fade, count, definition, lootable);
            }
            else if (lootable.Hack != null && definition != null && definition.Hack != null) {
                var time = lootable.GetHackTime();
                var totalTime = lootable.GetTotalHackingTime();
                if (lootable.IsHacking()) {
                    DrawInteractionBar(background, container, totalTime - time, totalTime, fade, -1, definition, textOne : $"{totalTime - time:0}s", textTwo : $"Please wait...", hackMode : true);
                }
            }
        }
        if (i != null && i.Value.IsLoadingTimer) {
            var span = DateTime.Now - i.Value.Timer;
            var value = definition.Timer - (float)span.TotalSeconds;
            var total = definition.Timer;
            DrawInteractionBar(background, container, value, total, fade, 0, definition, textOne : $"{value:0}s", textTwo : "", hackMode : true);
        }
        CuiHelper.AddUi(player, container);
        DrawnUI.Add(player);
    }
    public void UndrawInteraction(BasePlayer player, bool reset = true) {
        if (reset && !CUIPlayers.ContainsKey(player)) return;
        if (DrawnUI.Contains(player)) {
            for (int i = 0; i < ProcessorCount; i++) {
                CuiHelper.DestroyUi(player, CUICodeLockInputName);
            }
            for (int i = 0; i < ProcessorCount; i++) {
                CuiHelper.DestroyUi(player, CUIInteractionName);
            }
            for (int i = 0; i < ProcessorCount; i++) {
                CuiHelper.DestroyUi(player, CUIEditorInteractionName);
            }
            for (int i = 0; i < ProcessorCount; i++) {
                CuiHelper.DestroyUi(player, CUIEditorName);
            }
            DrawnUI.Remove(player);
        }
        if (reset) CUIPlayers.Remove(player);
    }
    public void DrawInteractionBar(string background, CuiElementContainer container, float value, float total, float fade, int count = -1, RootConfig.LootableDefinition definition = null, RootData.Lootable lootable = null, string textOne = null, string textTwo = null, bool hackMode = false) {
        container.Add(new CuiLabel {
            Text = {
                Text = textOne == null ? $"<b>{value:n0} / {total:n0}</b>".ToUpper() : textOne, FadeIn = fade, FontSize = 10, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperRight
            }
            , RectTransform = {
                AnchorMin = "0.3 0.9", AnchorMax = "0.7 1"
            }
        }
        , background);
        var bar = container.Add(new CuiPanel {
            Image = {
                Color = hackMode ? HackingColor : DamageColor, FadeIn = fade
            }
            , RectTransform = {
                AnchorMin = "0.3 0.925", AnchorMax = "0.7 0.95"
            }
            , CursorEnabled = false
        }
        , background);
        container.Add(new CuiPanel {
            Image = {
                Color = $"1 1 1 1", FadeIn = fade
            }
            , RectTransform = {
                AnchorMin = "0 0", AnchorMax = $"{Scale(value, 0f, total, 0f, 1f)} 1"
            }
            , CursorEnabled = false
        }
        , bar);
        if ((definition != null && Instance.Config.ShowLockedLootableApproximateCount) || textTwo != null) {
            var randomizer = GetSeededRandomizer(lootable == null ? definition.InteractionIndex : (int)(lootable.Position.x + lootable.Position.y + lootable.Position.z + definition.InteractionIndex));
            container.Add(new CuiLabel {
                Text = {
                    Text = textTwo == null ? $"~{randomizer.Next(count - 2, count + 2):n0} items appx.".ToUpper() : textTwo, FadeIn = fade, FontSize = 10, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperLeft
                }
                , RectTransform = {
                    AnchorMin = "0.3 0.9", AnchorMax = "0.7 1"
                }
            }
            , background);
            randomizer = null;
        }
    }
    private void DrawCodeLockInput(BasePlayer player) {
        if (!PinCache.ContainsKey(player)) PinCache.Add(player, string.Empty);
        for (int i = 0; i < 5; i++) {
            CuiHelper.DestroyUi(player, CUICodeLockInputName);
        }
        var container = new CuiElementContainer();
        var background = container.Add(new CuiPanel {
            Image = {
                Color = $"0.3 0.3 0.3 0.9", Material = "assets/content/ui/uibackgroundblur.mat"
            }
            , RectTransform = {
                AnchorMin = "0 0", AnchorMax = "1 1"
            }
            , CursorEnabled = true
        }
        , "Hud", CUICodeLockInputName, CUICodeLockInputName);
        container.Add(new CuiButton {
            Button = {
                Command = $"{CUIPinApplyCommand}", Color = "0 0 0 0"
            }
            , Text = {
                Text = string.Empty
            }
            , RectTransform = {
                AnchorMin = "0 0", AnchorMax = "1 1"
            }
        }
        , background);
        var panel = container.Add(new CuiPanel {
            Image = {
                Color = $"0 0 0 0"
            }
            , RectTransform = {
                AnchorMin = "0.425 0.35", AnchorMax = "0.575 0.7"
            }
            , CursorEnabled = false
        }
        , background);
        container.Add(new CuiLabel {
            Text = {
                Text = $"<b>{Config.CodeInputTitle}</b>".ToUpper(), FontSize = 18, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperCenter
            }
            , RectTransform = {
                AnchorMin = $"0 0.75", AnchorMax = $"1 0.985"
            }
        }
        , panel);
        var pinText = "";
        foreach (var number in PinCache[player]) pinText += $"{number}  ";
        var pin = container.Add(new CuiPanel {
            Image = {
                Color = $"0 0 0 0.5"
            }
            , RectTransform = {
                AnchorMin = "0.25 0.78", AnchorMax = "0.75 0.875"
            }
            , CursorEnabled = false
        }
        , panel);
        container.Add(new CuiLabel {
            Text = {
                Text = $"<b>{pinText.Trim()}</b>".ToUpper(), Color = "1 1 1 0.7", FontSize = 18, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter
            }
            , RectTransform = {
                AnchorMin = $"0 0", AnchorMax = $"1 1"
            }
        }
        , pin);
#region Buttons
        var offset = 0f;
        var horizontalOffset = 12f;
        var spacing = 37.5f;
        var count = 9;
        for (int i = 0; i < 3; i++) {
            container.Add(new CuiButton {
                Button = {
                    Command = $"{CUIPinAppendCommand} {count - 2}", Color = "0.8 0.8 0.8 0.35"
                }
                , Text = {
                    Text = $"<b>{count - 2}</b>", Align = TextAnchor.MiddleCenter, Color = "0.15 0.15 0.15 0.7", Font = "robotocondensed-regular.ttf", FontSize = 19
                }
                , RectTransform = {
                    AnchorMin = "0.2 0.62", AnchorMax = "0.35 0.75", OffsetMin = $"{horizontalOffset} {offset}", OffsetMax = $"{horizontalOffset} {offset}"
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"{CUIPinAppendCommand} {count - 1}", Color = "0.8 0.8 0.8 0.35"
                }
                , Text = {
                    Text = $"<b>{count - 1}</b>", Align = TextAnchor.MiddleCenter, Color = "0.15 0.15 0.15 0.7", Font = "robotocondensed-regular.ttf", FontSize = 19
                }
                , RectTransform = {
                    AnchorMin = "0.2 0.62", AnchorMax = "0.35 0.75", OffsetMin = $"{horizontalOffset + 32} {offset}", OffsetMax = $"{horizontalOffset + 32} {offset}"
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"{CUIPinAppendCommand} {count}", Color = "0.8 0.8 0.8 0.35"
                }
                , Text = {
                    Text = $"<b>{count}</b>", Align = TextAnchor.MiddleCenter, Color = "0.15 0.15 0.15 0.7", Font = "robotocondensed-regular.ttf", FontSize = 19
                }
                , RectTransform = {
                    AnchorMin = "0.2 0.62", AnchorMax = "0.35 0.75", OffsetMin = $"{horizontalOffset + 64} {offset}", OffsetMax = $"{horizontalOffset + 64} {offset}"
                }
            }
            , panel);
            offset -= spacing;
            count -= 3;
        }
        container.Add(new CuiButton {
            Button = {
                Command = $"{CUIPinAppendCommand} 0", Color = "0.8 0.8 0.8 0.35"
            }
            , Text = {
                Text = $"<b>0</b>", Align = TextAnchor.MiddleCenter, Color = "0.15 0.15 0.15 0.7", Font = "robotocondensed-regular.ttf", FontSize = 19
            }
            , RectTransform = {
                AnchorMin = "0.2 0.62", AnchorMax = "0.515 0.75", OffsetMin = $"{horizontalOffset} {offset}", OffsetMax = $"{horizontalOffset} {offset}"
            }
        }
        , panel);
        var acceptButton = container.Add(new CuiButton {
            Button = {
                Command = $"{CUIPinApplyCommand}", Color = "0.2 0.85 0.2 0.35"
            }
            , Text = {
                Text = string.Empty, Align = TextAnchor.MiddleCenter, Color = "0.15 0.15 0.15 0.7", Font = "robotocondensed-regular.ttf", FontSize = 19
            }
            , RectTransform = {
                AnchorMin = "0.535 0.62", AnchorMax = "0.68 0.75", OffsetMin = $"{horizontalOffset} {offset}", OffsetMax = $"{horizontalOffset} {offset}"
            }
        }
        , panel);
        container.Add(new CuiElement {
            Parent = acceptButton, Components = {
                Death.GetRawImage(Config.Urls.CheckUrl, color : "0.15 0.15 0.15 0.7"), new CuiRectTransformComponent {
                    AnchorMin = "0.2 0.22", AnchorMax = "0.8 0.78"
                }
            }
        }
        );
        offset -= spacing;
        container.Add(new CuiButton {
            Button = {
                Command = $"{CUIPinUndoCommand}", Color = "0.5 0.5 0.5 0.35"
            }
            , Text = {
                Text = $"<b>C</b>", Align = TextAnchor.MiddleCenter, Color = "1 1 1 0.4", Font = "robotocondensed-regular.ttf", FontSize = 19
            }
            , RectTransform = {
                AnchorMin = "0.2 0.62", AnchorMax = "0.68 0.75", OffsetMin = $"{horizontalOffset} {offset}", OffsetMax = $"{horizontalOffset} {offset}"
            }
        }
        , panel);
#endregion
        CuiHelper.AddUi(player, container);
        if (!CUIPlayers.ContainsKey(player)) CUIPlayers.Add(player, new PlayerInteraction());
    }
    public bool IsLootingLootable(BasePlayer player, RootData.Lootable lootable) {
        if (!CUIPlayers.ContainsKey(player)) return false;
        return CUIPlayers[player]?.Lootable == lootable;
    }
    [ConsoleCommand(CUIPinAppendCommand)]
    private void PinAppendCommand(ConsoleSystem.Arg arg) {
        var player = arg.Player();
        if (player == null) return;
        if (PinCache[player].Length >= 4) PinCache[player] = string.Empty;
        PinCache[player] += arg.Args[0];
        DrawCodeLockInput(player);
    }
    [ConsoleCommand(CUIPinApplyCommand)]
    private void PinApplyCommand(ConsoleSystem.Arg arg) {
        var player = arg.Player();
        if (player == null) return;
        var interaction = CUIPlayers[player];
        if (string.IsNullOrEmpty(PinCache[player]) || PinCache[player].Length < 4) {
            UndrawInteraction(player);
            PinCache[player] = string.Empty;
            return;
        }
        if (PinCache[player] == interaction?.Lootable.Hack.Code) {
            var definition = interaction?.Lootable.GetDefinition();
            var interactionDefinition = Config.Interactions[definition.InteractionIndex];
            PlayerLootContainer(player, definition, interaction?.Lootable, interactionDefinition, definition.Panel);
        }
        else {
            player.ChatMessage($"Wrong code for that static lootable container.");
        }
        PinCache[player] = string.Empty;
        UndrawInteraction(player);
    }
    [ConsoleCommand(CUIPinUndoCommand)]
    private void PinUndoCommand(ConsoleSystem.Arg arg) {
        var player = arg.Player();
        if (player == null) return;
        if (!string.IsNullOrEmpty(PinCache[player])) PinCache[player] = PinCache[player].Substring(0, PinCache[player].Length - 1);
        DrawCodeLockInput(player);
    }
#endregion
#region Override
    public class Death {
        public static string GetImage(string url, bool isPng = true, ulong imageId = 0) {
            try {
                var name = GetStringChecksum(url);
                if (string.IsNullOrEmpty(url)) return string.Empty;
                if ((bool)Instance.ImageLibrary.Call("HasImage", name, imageId)) {
                    var success = Instance.ImageLibrary.Call("GetImage", name, imageId);
                    return !isPng ? null : (string)success;
                }
                else {
                    Instance.ImageLibrary.Call("AddImage", url, name, imageId);
                    return !isPng ? url : null;
                }
            }
            catch {
                Instance.RefreshPlugins();
            }
            return string.Empty;
        }
        public static CuiRawImageComponent GetRawImage(string url, ulong skin = 0, string color = "", float fade = 0.3f) {
            var _url = GetImage(url, isPng : false, imageId : skin);
            var _png = GetImage(url, imageId : skin);
            return new CuiRawImageComponent {
                Url = _url, Png = _png, Color = color, FadeIn = fade
            }
            ;
        }
    }
    public static string GetStringChecksum(string value) {
        if (value.Length <= 3) return null;
        using (var md5 = MD5.Create()) {
            var hash = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(value));
            return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        }
    }
    private void OnServerInitialized() {
        Instance = this;
        RegisterPermissions();
        timer.Every(20, () => {
            ServerMgr.Instance.StartCoroutine(DoRefillingCalculations());
        }
        );
        LoadContainer();
        Log($"Initialized {Config.Definitions.Count:n0} lootables and {Data.Container.ItemContainer.itemList.Count:n0} persistent container(s).Poggers.");
        CreateBehaviour();
        foreach (var panel in PanelTypes) {
            PanelTypesList.Add(panel.Key);
        }
    }
    private void Loaded() {
        RefreshPlugins();
        if (ConfigFile == null) ConfigFile = new Core.Configuration.DynamicConfigFile($"{Manager.ConfigPath}/{Name}.json");
        if (DataFile == null) DataFile = Interface.Oxide.DataFileSystem.GetFile($"{Name}_data");
        if (!ConfigFile.Exists()) {
            ConfigFile.WriteObject(Config ?? (Config = new RootConfig()));
        }
        else {
            Config = ConfigFile.ReadObject<RootConfig>();
        }
        if (DataFile.Exists()) Data = DataFile.ReadObject<RootData>();
        else Data = new RootData();
        if (Instance == null) Instance = this;
    }
    private void Unload() {
        foreach (var player in CUIPlayers.ToArray()) {
            UndrawInteraction(player.Key);
            player.Key.inventory.loot.Clear();
            player.Key.inventory.loot.SendImmediate();
        }
        foreach (var player in Editors) {
            UndrawEditor(player.Key, false);
            UndrawEditorInteraction(player.Key);
        }
        foreach (var lootable in Data.Lootables) {
            lootable.ClearContainer();
        }
        Data.Lootables.Clear();
        Data.Container.ItemContainer?.Kill();
        ClearBehaviour();
        Instance = null;
    }
    private void OnServerSave() {
        SaveContainer();
        DataFile.WriteObject(Data ??= new RootData());
    }
    private void SaveConfig() {
        ConfigFile.WriteObject(Config ??= new RootConfig());
    }
    public void DoPlayerInput(BasePlayer player, InputState input) {
        if (Config == null || Instance == null) return;
        try {
            if (Config.AsyncMode) {
                if (!CoroutineBuffer.ContainsKey(player.userID)) CoroutineBuffer.Add(player.userID, true);
                else if (CoroutineBuffer[player.userID] && !input.WasJustPressed(BUTTON.USE) && !input.WasJustPressed(BUTTON.RELOAD)) return;
                CoroutineBuffer[player.userID] = true;
                player.StartCoroutine(DoPlayerInputCoroutine(player, input));
            }
            else {
                var loot = (RootData.Lootable)null;
                if (LootingPlayers.TryGetValue(player, out loot) && loot.TimeSinceDistanceCheck >= 0.5f) {
                    if (Vector3.Distance(player.eyes.position, PositionCache[player]) > Config.Distance) {
                        player.inventory.loot.Clear();
                        player.inventory.loot.SendImmediate();
                    }
                    loot.TimeSinceDistanceCheck = 0;
                }
                var didTrace = GamePhysics.Trace(player.eyes.HeadRay(), 0.0f, out var hitInfo, Config.Distance, ~0);
                if (!didTrace) {
                    if (CUIPlayers.ContainsKey(player)) {
                        var i = CUIPlayers[player].GetValueOrDefault();
                        i.Timer = DateTime.Now;
                        i.IsLoadingTimer = false;
                        i.Lootable?.CancelHack();
                        CUIPlayers[player] = i;
                    }
                    UndrawEditorInteraction(player);
                    UndrawInteraction(player);
                    return;
                }
                var obj = hitInfo.collider?.gameObject;
                if (obj == null) return;
                var name = obj.transform.GetRecursiveName();
                if (IsInEditMode(player)) {
                    if (input.WasJustPressed(BUTTON.RELOAD)) {
                        input.SwallowButton(BUTTON.RELOAD);
                        var editor = GetOrCreateEditor(player);
                        if (!editor.IsEditing) DrawEditor(player, EditModes.Settings);
                    }
                    if (!EditorInteractionPlayers.ContainsKey(player) || (EditorInteractionPlayers.ContainsKey(player) && EditorInteractionPlayers[player] != obj.transform)) {
                        if (!EditorInteractionPlayers.ContainsKey(player)) EditorInteractionPlayers.Add(player, obj.transform);
                        else EditorInteractionPlayers[player] = obj.transform;
                        DrawEditorInteraction(player, obj.transform);
                    }
                    if (input.WasJustPressed(BUTTON.USE)) {
                        input.SwallowButton(BUTTON.USE);
                        var editor = GetOrCreateEditor(player);
                        var definition = GetDefinition(obj.transform);
                        Editor.StartEdit(definition ?? new RootConfig.LootableDefinition(obj.transform.name.Split(' ')[0], 2, new List<RootLootableItemDefinition>()), editor.EditingDefinition);
                        editor.Transform = obj.transform;
                        DrawEditor(player);
                    }
                }
                else {
                    if (Config.MiddleMouseInfo && input.WasJustPressed(BUTTON.FIRE_THIRD) && permission.UserHasPermission(player.UserIDString, AdminPerm) && !player.IsHoldingEntity<BaseEntity>()) {
                        input.SwallowButton(BUTTON.FIRE_THIRD);
                        var ids = ZoneManager?.Call<string[]>("GetPlayerZoneIDs", player) ?? new string[0];
                        player.ChatMessage($"<size=10>Looking at:</size>\n<color=orange>{name}</color>\n" + $"<size=10>Zone(s) [{ids.Length:n0}]:</size>\n<color=orange>{(ids.Length == 0 ? "-" : string.Join(", ", ids))}</color>");
                        return;
                    }
                    var farAway = Vector3.Distance(hitInfo.point, player.transform.position) > Config.Distance;
                    var definition = GetDefinition(obj);
                    var interaction = definition == null ? null : Config.Interactions[definition.InteractionIndex];
                    var lootable = GetLootable(player, obj, definition, false);
                    var playerInteraction = !CUIPlayers.ContainsKey(player) ? null : CUIPlayers[player];
                    if (definition != null && definition.HasTimer() && lootable == null) lootable = GetLootable(player, obj, definition, true);
                    if (lootable != null && !lootable.IsLocked() && definition.HasTimer()) {
                        if (playerInteraction == null && !player.inventory.loot.IsLooting()) {
                            DrawInteraction(player, interaction, definition, lootable, true, reset : false);
                        }
                        var val = playerInteraction.GetValueOrDefault();
                        if (input.IsDown(BUTTON.USE)) {
                            if (!PositionCache.ContainsKey(player)) PositionCache.Add(player, hitInfo.point);
                            else PositionCache[player] = hitInfo.point;
                            if (input.WasJustPressed(BUTTON.USE)) {
                                val.Timer = DateTime.Now;
                                val.IsLoadingTimer = true;
                                CUIPlayers[player] = val;
                                DrawInteraction(player, interaction, definition, lootable, true, reset : false);
                            }
                            else if (val.IsLoadingTimer && val.TimerTime >= definition.Timer) {
                                input.SwallowButton(BUTTON.USE);
                                val.Timer = DateTime.Now;
                                val.IsLoadingTimer = false;
                                PlayerLootContainer(player, definition, lootable, interaction, definition.Panel);
                                CUIPlayers[player] = val;
                                UndrawInteraction(player, true);
                                return;
                            }
                        }
                        else {
                            val.IsLoadingTimer = false;
                            CUIPlayers[player] = val;
                            if (input.WasDown(BUTTON.USE) && !player.inventory.loot.IsLooting()) {
                                DrawInteraction(player, interaction, definition, lootable, false, reset : false);
                            }
                        }
                        CUIPlayers[player] = val;
                        if (!TimedPlayers.ContainsKey(player) || (TimedPlayers.ContainsKey(player) && TimedPlayers[player] >= Config.DamageCUIRefreshRate / 2)) {
                            if (input.IsDown(BUTTON.USE) && !player.inventory.loot.IsLooting()) DrawInteraction(player, interaction, definition, lootable, false, reset : false);
                            if (TimedPlayers.ContainsKey(player)) TimedPlayers[player] = 0f;
                            else TimedPlayers.Add(player, 0f);
                        }
                        return;
                    }
                    else {
                        var val = playerInteraction.GetValueOrDefault();
                        val.Timer = DateTime.Now;
                        val.IsLoadingTimer = false;
                        CUIPlayers[player] = val;
                    }
                    if (definition != null && !definition.Rule.IsValid(name, player)) return;
                    if (interaction == null && playerInteraction?.Interaction == interaction || playerInteraction?.Lock != lootable?.Lock || playerInteraction?.Interaction != interaction) {
                        if (lootable != null && lootable.HackingPlayer == player) {
                            lootable.CancelHack();
                        }
                        UndrawInteraction(player);
                    }
                    if (!farAway && definition != null && !player.inventory.loot.IsLooting() && !Config.IsFilteredOut(name) && Config.ZoneCheck(player)) {
                        if (definition.Lock != null || definition.Hack != null) lootable = GetLootable(player, obj, definition, true);
                        if (!CUIPlayers.ContainsKey(player) && !player.inventory.loot.IsLooting()) {
                            DrawInteraction(player, interaction, definition, lootable, true);
                        }
                    }
                    else {
                        if (lootable != null && lootable.HackingPlayer == player) {
                            lootable.CancelHack();
                        }
                        if (CUIPlayers.ContainsKey(player)) UndrawInteraction(player);
                    }
                    if (definition != null && !farAway) {
                        if (input.WasJustPressed(BUTTON.USE)) {
                            if (lootable == null) lootable = GetLootable(player, obj, definition, true);
                            if (lootable == null) return;
                            if (!PositionCache.ContainsKey(player)) PositionCache.Add(player, hitInfo.point);
                            else PositionCache[player] = hitInfo.point;
                            if (lootable.IsHackable() && !lootable.IsLocked() && !lootable.IsBusy(player)) {
                                lootable.StartHack(player);
                                DrawInteraction(player, interaction, definition, lootable, true, false);
                                lootable.Hack.HackingTimer = timer.Every(Config.DamageCUIRefreshRate, () => {
                                    if (!CUIPlayers.ContainsKey(player) || Vector3.Distance(PositionCache[player], player.transform.position) > Config.Distance) {
                                        if (lootable != null && lootable.HackingPlayer == player) {
                                            lootable.CancelHack();
                                        }
                                        UndrawInteraction(player);
                                        return;
                                    }
                                    if (lootable.HackHacked()) {
                                        var hackNote = ItemManager.CreateByName("note");
                                        hackNote.text = $"Successfully hacked! The code is: {lootable.Hack.Code}\n\nPress [RELOAD] to open the code input panel.";
                                        player.GiveItem(hackNote);
                                        lootable.Hack.HackedTimes++;
                                        if (lootable != null && lootable.HackingPlayer == player) {
                                            lootable.CancelHack();
                                        }
                                    }
                                    var players = CUIPlayers?.ToArray();
                                    for (int i = 0; i < players.Length; i++) {
                                        if (players[i].Value?.Lootable == lootable) {
                                            DrawInteraction(players[i].Key, interaction, definition, lootable, false, false);
                                        }
                                    }
                                    players = null;
                                }
                                );
                                return;
                            }
                            else if (lootable.IsHacking()) return;
                            if (!lootable.IsLocked() && CUIPlayers[player].Value.TimerTime >= definition.Timer) {
                                PlayerLootContainer(player, definition, lootable, interaction, definition.Panel);
                            }
                        }
                        else if (input.WasJustPressed(BUTTON.RELOAD) && !lootable.IsLocked() && lootable.IsHackable()) {
                            DrawCodeLockInput(player);
                        }
                    }
                }
            }
        }
        catch {
        }
    }
    private void OnPlayerAttack(BasePlayer player, HitInfo info) {
        if (Config == null || Instance == null) return;
        var didTrace = GamePhysics.Trace(player.eyes.HeadRay(), 0.0f, out var hitInfo, Config.Distance, ~0);
        if(!didTrace) return;
        var obj = hitInfo.collider?.gameObject;
        if (obj == null) return;
        var lootable = GetLootable(player, obj);
        if (lootable == null) return;
        var definition = lootable.GetDefinition();
        if (!lootable.IsLocked()) return;
        var multiplier = info.damageProperties.fallback.GetMultiplier(HitArea.Head);
        var damageAmount = GetRandomNumber(Config.DamageMultiplierMinimum, Config.DamageMultiplierMaximum) * multiplier;
        lootable.Lock.Health -= damageAmount;
        if (lootable.Lock.Health <= 0) {
            lootable.Lock = null;
        }
        if (!TimedPlayers.ContainsKey(player) || (TimedPlayers.ContainsKey(player) && TimedPlayers[player] >= Config.DamageCUIRefreshRate) || !lootable.IsLocked()) {
            ServerMgr.Instance.Invoke(() => {
                var players = CUIPlayers.ToArray();
                foreach (var cuiPlayer in players) {
                    if (cuiPlayer.Value?.Lootable == lootable) {
                        DrawInteraction(cuiPlayer.Key, Config.Interactions[definition.InteractionIndex], definition, lootable, false);
                    }
                }
                players = null;
            }
            , 0.2f);
            TimedPlayers[player] = 0;
        }
        player?.SendConsoleCommand("gametip.hidegametip");
    }
    private void OnPlayerLootEnd(PlayerLoot inventory) {
        var player = inventory.baseEntity;
        if (player == null) return;
        UndrawInteraction(player, reset : true);
        if (LootingPlayers.ContainsKey(player)) LootingPlayers.Remove(player);
        if (CUIPlayers.ContainsKey(player)) CUIPlayers[player] = null;
    }
    private void OnPluginLoaded(Plugin name) {
        RefreshPlugins();
    }
    private void OnPluginUnloaded(Plugin name) {
        RefreshPlugins();
    }
    private void OnNewSave(string filename) {
        DataFile.WriteObject(Data = new RootData());
    }
    private void OnEntityKill(TimedExplosive entity) {
        var colliders = Facepunch.Pool.GetList<Collider>();
        Vis.Colliders(entity.transform.position, entity.explosionRadius, colliders);
        foreach (var collider in colliders) {
            var lootable = GetLootable(null, collider.gameObject);
            if (lootable != null && lootable.IsLocked()) {
                lootable.Lock.Health -= entity.damageTypes.Sum(x => x.amount);
                if (lootable.Lock.Health <= 0) lootable.Lock = null;
            }
        }
        Facepunch.Pool.FreeList(ref colliders);
    }
    private readonly static string[] CommandSplit = new string[] {
        " "
    }
    ;
    private readonly static string[] EmptyArgs = new string[0];
    public static void PlayerLootContainer(BasePlayer player, RootConfig.LootableDefinition definition, RootData.Lootable lootable, RootConfig.Interaction interaction, string lootPanel) {
        player.serverInput.SwallowButton(BUTTON.USE);
        var cui = Instance.CUIPlayers[player].GetValueOrDefault();
        if (cui.IsProcessingCommand) {
            return;
        }
        if (!string.IsNullOrEmpty(interaction.OpenEffect)) {
            SendEffectTo(interaction.OpenEffect, player);
        }
        if (!string.IsNullOrEmpty(definition.Command)) {
            cui.IsProcessingCommand = true;
            Instance.CUIPlayers[player] = cui;
            Instance.DrawInteraction(player, interaction, definition, lootable, false, false, reset : false);
            Instance.timer.In(0.5f, () => {
                var credential = ConsoleSystem.Option.Unrestricted.FromConnection(player.net.connection);
                var split = definition.Command.Split(CommandSplit, StringSplitOptions.RemoveEmptyEntries);
                var command = split.Length > 1 ? split[0] : definition.Command;
                ConsoleSystem.Run(credential, command, split.Length <= 1 ? EmptyArgs : split.Skip(1).ToArray());
                cui.IsProcessingCommand = false;
                Instance.CUIPlayers[player] = cui;
                Instance.DrawInteraction(player, interaction, definition, lootable, false, reset : false);
            }
            );
            return;
        }
        player.inventory.loot.Clear();
        player.inventory.loot.PositionChecks = false;
        player.inventory.loot.entitySource = RelationshipManager.ServerInstance;
        player.inventory.loot.itemSource = null;
        player.inventory.loot.AddContainer(lootable.GetContainer(definition.ContainerSize, definition.Liquid, definition.AllowStack));
        player.inventory.loot.MarkDirty();
        player.inventory.loot.SendImmediate();
        lootable.ContainerOwnership(player);
        player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", lootPanel);
        Instance.QuickSort?.CallHook("OnLootPlayer", player);
        Instance.UndrawInteraction(player, true);
        if (!Instance.LootingPlayers.ContainsKey(player)) Instance.LootingPlayers.Add(player, lootable);
    }
    public static ItemContainer CreateContainer(int capacity = 1, bool liquid = false) {
        var container = new ItemContainer {
            isServer = true, allowedContents = liquid ? ItemContainer.ContentsType.Liquid : ItemContainer.ContentsType.Generic, capacity = capacity
        }
        ;
        container.GiveUID();
        return container;
    }
    public Dictionary<ulong, bool> CoroutineBuffer {
        get;
        private set;
    }
    = new();
    public IEnumerator DoPlayerInputCoroutine(BasePlayer player, InputState input) {
        var loot = (RootData.Lootable)null;
        if (LootingPlayers.TryGetValue(player, out loot) && loot?.TimeSinceDistanceCheck >= 0.5f) {
            if (Vector3.Distance(player.eyes.position, PositionCache[player]) > Config.Distance) {
                player.inventory.loot.Clear();
                player.inventory.loot.SendImmediate();
            }
            loot.TimeSinceDistanceCheck = 0;
        }
        if (!GamePhysics.Trace(player.eyes.HeadRay(), 0.0f, out var hitInfo, Config.Distance, ~0)) {
            if (CUIPlayers.ContainsKey(player)) {
                var i = CUIPlayers[player].GetValueOrDefault();
                i.Timer = DateTime.Now;
                i.IsLoadingTimer = false;
                i.Lootable?.CancelHack();
                CUIPlayers[player] = i;
            }
            UndrawEditorInteraction(player);
            UndrawInteraction(player);
            CoroutineBuffer[player.userID] = false;
            yield break;
        }
        var obj = hitInfo.collider?.gameObject;
        if (obj== null) {
            CoroutineBuffer[player.userID] = false;
            yield break;
        }
        var name = obj.transform.GetRecursiveName();
        try {
            if (IsInEditMode(player)) {
                if (input.WasJustPressed(BUTTON.RELOAD)) {
                    input.SwallowButton(BUTTON.RELOAD);
                    var editor = GetOrCreateEditor(player);
                    if (!editor.IsEditing) DrawEditor(player, EditModes.Settings);
                }
                if (obj != null) {
                    if (!EditorInteractionPlayers.ContainsKey(player) || (EditorInteractionPlayers.ContainsKey(player) && EditorInteractionPlayers[player] != obj.transform)) {
                        if (!EditorInteractionPlayers.ContainsKey(player)) EditorInteractionPlayers.Add(player, obj.transform);
                        else EditorInteractionPlayers[player] = obj.transform;
                        DrawEditorInteraction(player, obj.transform);
                    }
                }
                if (input.WasJustPressed(BUTTON.USE)) {
                    input.SwallowButton(BUTTON.USE);
                    var editor = GetOrCreateEditor(player);
                    var definition = GetDefinition(obj.transform);
                    Editor.StartEdit(definition ?? new RootConfig.LootableDefinition(obj.transform.name.Split(' ')[0], 2, new List<RootLootableItemDefinition>()), editor.EditingDefinition);
                    editor.Transform = obj.transform;
                    DrawEditor(player);
                }
            }
            else {
                if (Config.MiddleMouseInfo && input.WasJustPressed(BUTTON.FIRE_THIRD) && permission.UserHasPermission(player.UserIDString, AdminPerm) && !player.IsHoldingEntity<BaseEntity>()) {
                    input.SwallowButton(BUTTON.FIRE_THIRD);
                    var ids = ZoneManager?.Call<string[]>("GetPlayerZoneIDs", player) ?? new string[0];
                    player.ChatMessage($"<size=10>Looking at:</size>\n<color=orange>{name}</color>\n" + $"<size=10>Zone(s) [{ids.Length:n0}]:</size>\n<color=orange>{(ids.Length == 0 ? "-" : string.Join(", ", ids))}</color>");
                    CoroutineBuffer[player.userID] = false;
                    yield break;
                }
                var farAway = Vector3.Distance(hitInfo.point, player.transform.position) > Config.Distance;
                var definition = GetDefinition(obj);
                var interaction = definition == null ? null : Config.Interactions[definition.InteractionIndex];
                var lootable = GetLootable(player, obj, definition, false);
                var playerInteraction = !CUIPlayers.ContainsKey(player) ? null : CUIPlayers[player];
                if (definition != null && !definition.Rule.IsValid(name, player)) {
                    CoroutineBuffer[player.userID] = false;
                    yield break;
                }
                if (definition != null && definition.HasTimer() && lootable == null) lootable = GetLootable(player, obj, definition, true);
                if (lootable != null && !lootable.IsLocked() && definition.HasTimer()) {
                    if (playerInteraction == null && !player.inventory.loot.IsLooting()) {
  
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху