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

FREE HammerRemove : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using Oxide.Core.Plugins;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("HammerRemove", "i3ladik", "1.0.0")]
	[Description("Ремув с помощью удара киянкой с зажатой кнопкой")]
    public class HammerRemove : RustPlugin
    {
        [PluginReference] Plugin Clans, Friends, NoEscape;
        static Configuration config = new Configuration();
        private static Dictionary<uint, RemovableObject> RemovableInfos = new Dictionary<uint,RemovableObject>();
        private static Dictionary<string, int> deployedToItem = new Dictionary<string, int>();
        private static double CurrentTime() => DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; 
        private static BUTTON _removeButton;

        class Configuration
        {
            [JsonProperty("Кнопка для удаления (FORWARD/BACKWARD/LEFT/RIGHT/JUMP/DUCK/SPRINT/USE/FIRE_PRIMARY/FIRE_SECONDARY/RELOAD/FIRE_THIRD)")]            
            public string removeButton;
            [JsonProperty("Время удаления построек")]
            public double bRemoveTime;
            [JsonProperty("Включить запрет на удаление объекта если в его инвентаре есть предметы")]
            public bool checkRemoveItems;
            [JsonProperty("Процент возвращаемых ресурсов с предметов (1.0 - 100%)")]
            public float refundItemsPercent;
            [JsonProperty("Процент возвращаемых ресурсов с построек (1.0 - 100%)")]
            public float refundPercent;
            [JsonProperty("Включить возрат предметов (будут возвращаться предметы а не ресурсы)")]
            public bool refundItemsGive;
            [JsonProperty("Процент выпадающих ресурсов (не вещей) с удаляемых ящиков (1.0 - 100%)")]
            public float refundStoragePercent;
            [JsonProperty("Разрешить удаление объектов друзей без авторизации в шкафу")]
            public bool friendRemove;
            [JsonProperty("Разрешить удаление объектов соклановцев без авторизации в шкафу")]
            public bool clanRemove;
            [JsonProperty("Разрешить удаление объектов тиммейтов (RUST) без авторизации в шкафу")]
            public bool teamRemove;
            [JsonProperty("Разрешить удаление чужих объектов при наличии авторизации в шкафу")]
            public bool cupboardRemove;
            [JsonProperty("Разрешить удаление собственных объектов без авторизации в шкафу")]
            public bool selfRemove;
            [JsonProperty("Включить поддержку NoEscape")]
            public bool useNoEscape;
            [JsonProperty("Разрешить удаление обьектов друзьям")]
            public bool removeFriends;
            [JsonProperty("Разрешить удаление объектов соклановцев")]
            public bool removeClans;
            [JsonProperty("Разрешить удаление объектов тиммейтов (RUST)")]
            public bool removeTeam;
            [JsonProperty("Черный список удаления")]
            public List<string> blackList = new List<string>();
            public static Configuration GetNewConfiguration()
            {
                return new Configuration
                {
                    removeButton = BUTTON.RELOAD.ToString(),
                    bRemoveTime = 21600,
                    checkRemoveItems = true,
                    refundItemsPercent = 1.0f,
                    refundPercent = 1.0f,
                    refundItemsGive = true,
                    refundStoragePercent = 1.0f,
                    friendRemove = false,
                    clanRemove = false,
                    teamRemove = false,
                    cupboardRemove = true,
                    selfRemove = false,
                    useNoEscape = false,
                    removeFriends = false,
                    removeClans = false,
                    removeTeam = true,
                    blackList = new List<string>
                    {
                        "small_stash_deployed"
                    }
                };
            }
        } 
        private class RemovableObject
        {
            [JsonProperty("S")]
            public bool isInteractable;
            [JsonProperty("T")]
            public long buildTime; 
            [JsonIgnore]
            public long lastAttackedTime;

            public string Label() => isInteractable ? $"<size=14>РЕМУВ/ПОВОРОТ ДОСТУПЕН</size>\n" : $"<size=14>РЕМУВ/ПОВОРОТ ОТНЫНЕ НЕ ДОСТУПЕН</size>\n";

            public string InteractStatus(bool admin = false)
            {
                if (!isInteractable)
                {
                    if (buildTime < 0)
                        return $"{Label()}"  + "<size=13>ИСТЕКЛО ВРЕМЯ УДАЛЕНИЯ</size>\n<color=#d3c9c0>✕</color>";
                    
                    return $"{Label()}" + "<size=13>ДОМ БЫЛ ПОДВЕРЖЕН РЕЙДУ</size>\n<color=#d3c9c0>✕</color>";
                }
                
                if (CurrentTime() >= (buildTime + config.bRemoveTime))  
                {
                    isInteractable = false;
                    buildTime = -1;  

                    return InteractStatus(); 
                }

                var totalTime = TimeSpan.FromSeconds((buildTime + config.bRemoveTime) - CurrentTime());
                
                return $"<size=18>{Label()}</size>" +
                        $"<size=16>{totalTime.Hours}ч.{totalTime.Minutes}м.</size>";
            }

            public string BuildTimeConverted()
            {
                var date = DateTime.FromFileTime(buildTime);
                return $"{date.ToShortDateString()} {date.ToShortTimeString()}";
            }

            public static RemovableObject Generate(BuildingBlock obj)
            {
                return new RemovableObject
                {
                    isInteractable = true,
                    buildTime = (long) CurrentTime()
                }; 
            }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
            }
            catch
            {
                PrintWarning($"Ошибка чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
                LoadDefaultConfig();
            }
            NextTick(SaveConfig);
        }
		
		protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
        protected override void SaveConfig() => Config.WriteObject(config);

        private void Unload() => SaveData();

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(Name, RemovableInfos);
        } 
        
        private void OnServerInitialized()
        {

            if (Interface.Oxide.DataFileSystem.ExistsDatafile(Name))
                RemovableInfos = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<uint, RemovableObject>>(Name);

            var dirty = new List<uint>();
            foreach (var check in RemovableInfos.Where(p => BaseNetworkable.serverEntities.Find(p.Key)?.IsDestroyed ?? true))
                dirty.Add(check.Key);

            foreach (var check in dirty)
                RemovableInfos.Remove(check);
            
            SaveData();
            
            UnityEngine.Object.FindObjectsOfType<BuildingBlock>().ToList().ForEach(p =>
            {
                if (!RemovableInfos.ContainsKey(p.net.ID))
                    RemovableInfos.Add(p.net.ID, RemovableObject.Generate(p));
                
                p.SetFlag(BaseEntity.Flags.Reserved1, true);
                p.SetFlag(BaseEntity.Flags.Reserved2, true);
                p.CancelInvoke(p.StopBeingRotatable);
                p.CancelInvoke(p.StopBeingDemolishable); 
            });

            deployedToItem.Clear();
            List<ItemDefinition> ItemsDefinition = ItemManager.GetItemDefinitions() as List<ItemDefinition>;
            foreach (ItemDefinition itemdef in ItemsDefinition)
            {
                if (itemdef?.GetComponent<ItemModDeployable>() == null) continue;
                if (deployedToItem.ContainsKey(itemdef.GetComponent<ItemModDeployable>().entityPrefab.resourcePath)) continue;
                deployedToItem.Add(itemdef.GetComponent<ItemModDeployable>().entityPrefab.resourcePath, itemdef.itemid);
            }

            lang.RegisterMessages(Messages, this, "ru");
            Messages = lang.GetMessages("ru", this);

            if (!Enum.TryParse(config.removeButton, true, out _removeButton) || !Enum.IsDefined(typeof(BUTTON), _removeButton))
            {
                PrintError($"{config.removeButton} неподходящая кнопка.Конфиг изменен на кнопку 'RELOAD'.");
                _removeButton = BUTTON.RELOAD;
                config.removeButton = _removeButton.ToString();
                SaveConfig();
            }

            timer.Every(600, SaveData);
        }

        private object OnHammerHit(BasePlayer player, HitInfo info)
        {
            if (info == null || player == null) return null;
            var entity = info?.HitEntity;
            if (entity == null) return null;
            if (entity.IsDestroyed) return false;
            if (entity.OwnerID == 0) return null;
            if (entity.ShortPrefabName.Contains("recycler")) return false;
            if ((!(entity is DecayEntity) && !(entity is Signage)) && !entity.ShortPrefabName.Contains("shelves") && !entity.ShortPrefabName.Contains("ladder") && !entity.ShortPrefabName.Contains("quarry")) return null;
            if (!entity.OwnerID.IsSteamId()) return null;
            var privilege = player.GetBuildingPrivilege(player.WorldSpaceBounds());

            if (player.serverInput.IsDown(_removeButton))
            {

                StorageContainer storage = entity as StorageContainer;
                if (storage && config.checkRemoveItems)
                {
                    if (storage.inventory.itemList.Count > 0)
                    {
                        SendReply(player, Messages["CheckItems"]);
                        return false;
                    }
                }
                var externalPlugins = Interface.CallHook("canRemove", player);
                if (externalPlugins != null)
                {
                SendReply(player, Messages["RET"]);
                    return false;
                }
                if (config.useNoEscape)
                {
                    if (plugins.Exists("NoEscape"))
                    {
                        var isRaid = (bool)NoEscape?.Call("IsRaidBlocked", player.userID);
                        if (isRaid)
                        {
                            SendReply(player, Messages["NoEscape"]);
                            return false;
                        }
                    }
                }
                if (config.blackList.Contains(entity.ShortPrefabName))
                {
                    SendReply(player, Messages["EntityBlackListed"]);
                    return false;
                }
                if (config.cupboardRemove)
                {
                    if (privilege != null && player.IsBuildingAuthed())
                    {
                        RemoveEntity(player, entity);
                        return true;
                    }
                }
                if (privilege != null && !player.IsBuildingAuthed())
                {
                    if (config.selfRemove && entity.OwnerID == player.userID)
                    {
                        RemoveEntity(player, entity);
                        return true;
                    }
                    if (config.friendRemove)
                    {
                        if (config.removeFriends)
                        {
                            if (IsFriends(entity.OwnerID, player.userID))
                            {
                                RemoveEntity(player, entity);
                                return true;
                            }
                        }
                    }
                    if (config.clanRemove)
                    {
                        if (config.removeClans)
                        {
                            if (IsClanMember(entity.OwnerID, player.userID))
                            {
                                RemoveEntity(player, entity);
                                return true;
                            }
                        }
                    }
                    if (config.teamRemove)
                    {
                        if (config.removeTeam)
                        {
                            if (IsTeamate(BasePlayer.FindByID(entity.OwnerID), player.userID))
                            {
                                if (!config.selfRemove && entity.OwnerID == player.userID)
                                {
                                    SendReply(player, Messages["ownerCup"]);
                                    return false;
                                }
                                RemoveEntity(player, entity);
                                return true;
                            }
                        }
                    }
                    SendReply(player, Messages["ownerCup"]);
                    return false;
                }
                if (entity.OwnerID != player.userID)
                {
                    if (config.removeFriends)
                    {
                        if (IsFriends(entity.OwnerID, player.userID))
                        {
                            RemoveEntity(player, entity);
                            return true;
                        }
                    }
                    if (config.removeClans)
                    {
                        if (IsClanMember(entity.OwnerID, player.userID))
                        {
                            RemoveEntity(player, entity);
                            return true;
                        }
                    }
                    if (config.removeTeam)
                    {
                        if (IsTeamate(BasePlayer.FindByID(entity.OwnerID), player.userID))
                        {
                            if (!config.selfRemove && entity.OwnerID == player.userID)
                            {
                                SendReply(player, Messages["ownerCup"]);
                                return false;
                            }
                            RemoveEntity(player, entity);
                            return true;
                        }
                    }
                    SendReply(player, Messages["norights"]);
                    return false;
                }
                RemoveEntity(player, entity);
                return true;
            }
            else
            {
                if (privilege != null && player.IsBuildingAuthed())
                {
                    RemovableObject removeInfo;
                    if (!RemovableInfos.TryGetValue(entity.net.ID, out removeInfo) || CurrentTime() < removeInfo.lastAttackedTime + 10) return null;
                    SendMarker(player, info.PointEnd, removeInfo.InteractStatus());
                    removeInfo.lastAttackedTime = (long) CurrentTime();
                    return null; 
                }
                return null; 
            }
        }

        void RemoveEntity(BasePlayer player, BaseEntity entity)
        {
            if (!CheckRemoveInteractable(player, entity)) return;
            Refund(player, entity);
            NextFrame(() =>
            {
                entity.Kill();
            });
        }

        bool CheckRemoveInteractable(BasePlayer player, BaseEntity entity)
        {
            RemovableObject removeInfo;
            if (RemovableInfos.TryGetValue(entity.net.ID, out removeInfo))
            {
                var result = removeInfo.InteractStatus();
                if (!removeInfo.isInteractable)
                {
                    RaycastHit infohit;
                    Physics.Raycast(player.eyes.position, player.eyes.HeadForward(), out infohit);

                    if (CurrentTime() < removeInfo.lastAttackedTime + 3)
                    {
                        return  false; 
                    }
                    SendMarker(player, infohit.point, result);
                    return  false;  
                }else return  true;
            }else return  true;
        }


        void OnNewSave()
        {
            Puts("Обнаружен вайп.Очищаем сохраненные объекты");
            RemovableInfos.Clear();
            SaveData();
        }

        private void BlockObject(BuildingBlock obj)
        {
            if (!RemovableInfos.ContainsKey(obj.net.ID))
                RemovableInfos.Add(obj.net.ID, RemovableObject.Generate(obj));

            var info = RemovableInfos[obj.net.ID];
            info.isInteractable = false;
        }

        private void OnEntitySpawned(BaseEntity entity)
        {
            var obj = entity as BuildingBlock;
            if (obj == null) return; 
            
            if (!RemovableInfos.ContainsKey(obj.net.ID))
                RemovableInfos.Add(obj.net.ID, RemovableObject.Generate(obj));
            
            NextTick(() =>
            {
                obj.CancelInvoke(obj.StopBeingRotatable);
                obj.CancelInvoke(obj.StopBeingDemolishable);
            });
        }
        
        private object OnStructureDemolish(BuildingBlock block, BasePlayer player)
        { 
            RemovableObject removeInfo;
            if (RemovableInfos.TryGetValue(block.net.ID, out removeInfo))
            {
                var result = removeInfo.InteractStatus();
                if (!removeInfo.isInteractable)
                {
                    RaycastHit info;
                    Physics.Raycast(player.eyes.position, player.eyes.HeadForward(), out info);

                    if (CurrentTime() < removeInfo.lastAttackedTime + 3)
                    {
                        return false; 
                    }
                    SendMarker(player, info.point, result); 
                    return false; 
                }
            }
            
            return null;
        }

        private object OnStructureRotate(BuildingBlock block, BasePlayer player)
        { 
            RemovableObject removeInfo;
            if (RemovableInfos.TryGetValue(block.net.ID, out removeInfo))
            {
                RaycastHit info;
                Physics.Raycast(player.eyes.position, player.eyes.HeadForward(), out info);
                
                var result = removeInfo.InteractStatus();
                if (!removeInfo.isInteractable)
                {
                    if (CurrentTime() < removeInfo.lastAttackedTime + 3)
                    {
                        return false; 
                    }
                    SendMarker(player, info.point, result); 
                    return false;
                }   
            }
            
            return null;
        }

        void Refund(BasePlayer player, BaseEntity entity)
        {
            if (entity is BuildingBlock)
            {
                BuildingBlock buildingblock = entity as BuildingBlock;
                if (buildingblock.blockDefinition == null) return;
                int buildingblockGrade = (int)buildingblock.grade;
                if (buildingblock.blockDefinition.grades[buildingblockGrade] != null)
                {
                    float refundRate = buildingblock.healthFraction * config.refundPercent;
                    List<ItemAmount> currentCost = buildingblock.blockDefinition.grades[buildingblockGrade].costToBuild as List<ItemAmount>;
                    foreach (ItemAmount ia in currentCost)
                    {
                        int amount = (int)(ia.amount * refundRate);
                        if (amount <= 0 || amount > ia.amount || amount >= int.MaxValue) amount = 1;
                        if (refundRate != 0)
                        {
                            Item x = ItemManager.CreateByItemID(ia.itemid, amount);
                            player.GiveItem(x, BaseEntity.GiveItemReason.PickedUp);
                        }
                    }
                }
                return;
            }
            StorageContainer storage = entity as StorageContainer;
            if (storage)
            {
                if (storage.inventory.itemList.Count > 0) for (int i = storage.inventory.itemList.Count - 1;
                i >= 0;
                i--)
                    {
                        var item = storage.inventory.itemList[i];
                        if (item == null) continue;
                        if (item.info.shortname == "water") continue;
                        item.amount = (int)(item.amount * config.refundStoragePercent);
                        float single = 20f;
                        Vector3 vector32 = Quaternion.Euler(UnityEngine.Random.Range(-single * 0.1f, single * 0.1f), UnityEngine.Random.Range(-single * 0.1f, single * 0.1f), UnityEngine.Random.Range(-single * 0.1f, single * 0.1f)) * Vector3.up;
                        BaseEntity baseEntity = item.Drop(storage.transform.position + (Vector3.up * 0f), vector32 * UnityEngine.Random.Range(5f, 10f), UnityEngine.Random.rotation);
                        baseEntity.SetAngularVelocity(UnityEngine.Random.rotation.eulerAngles * 5f);
                    }
            }
            if (deployedToItem.ContainsKey(entity.gameObject.name))
            {
                ItemDefinition def = ItemManager.FindItemDefinition(deployedToItem[entity.gameObject.name]);
                foreach (var ingredient in def.Blueprint.ingredients)
                {
                    var reply = 1;
                    if (reply == 0) { }
                    var amountOfIngridient = ingredient.amount;
                    var amount = Mathf.Floor(amountOfIngridient * config.refundItemsPercent);
                    if (amount <= 0 || amount > amountOfIngridient || amount >= int.MaxValue) amount = 1;
                    if (!config.refundItemsGive)
                    {
                        if (config.refundItemsPercent != 0)
                        {
                            Item x = ItemManager.Create(ingredient.itemDef, (int)amount);
                            player.GiveItem(x, BaseEntity.GiveItemReason.PickedUp);
                        }
                    }
                    else
                    {
                        GiveAndShowItem(player, deployedToItem[entity.PrefabName], 1, entity.skinID);
                        return;
                    }
                }
            }
        }

        void GiveAndShowItem(BasePlayer player, int item, int amount, ulong skin)
        {
            Item x = ItemManager.CreateByItemID(item, amount, skin);
            player.GiveItem(x, BaseEntity.GiveItemReason.PickedUp);
        }

        private static void SendMarker(BasePlayer player, Vector3 position, string text)
        {
            player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true); 
                    
            player.SendEntityUpdate();   
            player.SendConsoleCommand("ddraw.text", 2f, Color.white, position, text);
                    
            if (player.Connection.authLevel < 2)
            {
                player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);  
                player.SendConsoleCommand("camspeed 0");
            }
                    
            player.SendEntityUpdate();
			
        }

        bool IsClanMember(ulong playerID, ulong targetID)
        {
            if (plugins.Exists("Clans")) return (bool)(Clans?.Call("IsClanMember", playerID, targetID) ?? false);
            return false;
        }
        bool IsFriends(ulong playerID, ulong friendId, ulong playerid = 1)
        {
            if (plugins.Exists("Friends")) return (bool)(Friends?.Call("AreFriends", playerID, friendId) ?? false);
            return false;
        }
        bool IsTeamate(BasePlayer player, ulong targetID)
        {
            if (player.currentTeam < 2) return false;
            var team = RelationshipManager.ServerInstance.FindTeam(player.currentTeam);
            if (team == null) return false;
            var list = RelationshipManager.ServerInstance.FindTeam(player.currentTeam).members.Where(p => p == targetID).ToList();
            return list.Count > 0;
        }

        Dictionary<string, string> Messages = new Dictionary<string, string>() {
                {
                "NoEscape", "Удаление построек во время рейдблока запрещёно!"
            }
            , {
                "ownerCup", "Что бы удалять постройки, вы должны быть авторизированы в шкафу"
            }
            , {
                "norights", "Вы не имеете права удалять чужие постройки!"
            }
            , {
                "RET", "Не удалось использовать удаление постройки: внешний фактор заблокировал его использование"
            }
            , {
                "CheckItems", "Не удалось использовать удаление предмета: в его инвентаре есть предметы, очистите их"
            }
            , {
                "EntityBlackListed", "Не удалось использовать удаление предмета: он находиться в черном списке."
            }
            ,
        };
    }
}

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

Другие ресурсы пользователя 15FPS

Сверху