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

FREE CustomPortals : 1.3.8 1.3.8

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
 //#define DEBUG
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace Oxide.Plugins {
    [Info("CustomPortals", "_senyaa", "1.3.8")]
    class CustomPortals : RustPlugin {
#region Dependencies
        [PluginReference]
        Plugin ServerRewards, NoEscape, Clans, Economics;
        static bool? TakePoints(ulong playerID, int amount) => Instance.ServerRewards?.Call("TakePoints", playerID, amount) as bool?;
        static int? CheckPoints(ulong ID) => Instance.ServerRewards?.Call("CheckPoints", ID) as int?;
        static bool? IsRaidBlocked(string target) => Instance.NoEscape?.Call("IsRaidBlocked", target) as bool?;
        static bool? IsCombatBlocked(string target) => Instance.NoEscape?.Call("IsCombatBlocked", target) as bool?;
        static bool? IsClanMember(string playerId, string otherId) => Instance.Clans?.Call("IsClanMember", playerId, otherId) as bool?;
        static bool? IsMemberOrAlly(string playerId, string otherId) => Instance.Clans?.Call("IsMemberOrAlly", playerId, otherId) as bool?;
        static bool? Economics_Withdraw(string playerId, double amount) => Instance.Economics?.Call("Withdraw", playerId, amount) as bool?;
#endregion
#region Constants
        const string PORTAL_PREFAB = "assets/prefabs/missions/portal/halloweenportalexit.prefab";
        const string RADIUS_MAP_MARKER_PREFAB = "assets/prefabs/tools/map/genericradiusmarker.prefab";
        const string VENDING_MAP_MARKER_PREFAB = "assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab";
        const string SET_PORTAL_NAME_CCMD = "customportals.portalname.set";
        const string SAVE_PORTAL_NAME_CCMD = "customportals.portalname.save";
        const string CANCEL_PORTAL_NAME_CCMD = "customportals.portalname.cancel";
        const string TOGGLE_PORTAL_BROADCAST_CCMD = "customportals.togglebroadcast";
        const string SET_PORTAL_PERMISSION_CCMD = "customportals.permission.set";
        const string SAVE_PORTAL_PERMISSION_CCMD = "customportals.permission.save";
        const string RENAMING_CUI_NAME = "CustomPortals_RenameUI";
        const string DEBUG_CUI_NAME = "CustomPortals_6ebugUI";
        const string HP_BAR_CUI_NAME = "CustomPortals_HPBar";
        const int HAMMER_ITEMID = 200773292;
        const string ADMIN_PERMISSION = "customportals.admin";
        const string PORTAL_BUY_PERMISSION = "customportals.buy";
        const string PORTAL_FREE_PERMISSION = "customportals.free";
        const string PORTAL_USE_PERMISSION = "customportals.use";
        const string PORTAL_FREE_ENTRY_PERMISSION = "customportals.freeuse";
        const string PORTAL_LIMIT_BYPASS_PERMISSION = "customportals.bypasslimit";
        const string PORTAL_BYPASS_LINKING_LIMITATIONS = "customportals.bypasslinkinglimits";
        const string PORTAL_SPAWN_PERMISSION = "customportals.spawn";
        const string PERMISSION_GROUP_PREFIX = "customportals.group.";
        const string PLAYER_DATA_FILENAME = "CustomPortals_PlayerGeneratedData";
        const string MONUMENT_DATA_FILENAME = "CustomPortals_MonumentData";
        const string CACHED_MAP_DATA_FILENAME = "CustomPortals_CachedCustomMapData";
        static Vector3 PORTAL_PLACEMENT_OFFSET = new Vector3(0, 0.35f, 0);
        static LayerMask PLAYER_LAYER_MASK = LayerMask.GetMask("Player (Server)");
        static LayerMask OBSTRUCTION_MASK = LayerMask.GetMask(new[] {
            "Construction", "Deployed", "World", "Terrain"
        }
        );
#endregion
#region Configuration
        class Configuration : SerializableConfiguration {
            [JsonProperty("(0.1) Portal Price (set value to 0 to make it free, use ServerRewards or Economics as a shortname to use RP points or Economics balance respectively)")]
            public Price PortalPrice = new Price {
                ShortName = "scrap", Amount = 150, SkinID = 0
            }
            ;
            //            public KeyValuePair<string, int> PortalPrice = new KeyValuePair<string, int>("scrap", 150);
            [JsonProperty("(0.2) Entry price (set value to 0 to make it free, use ServerRewards or Economics as a shortname to use RP points or Economics balance respectively)")]
            public Price PricePerEntry = new Price {
                ShortName = "scrap", Amount = 0, SkinID = 0
            }
            ;
            //            public KeyValuePair<string, int> PricePerEntry = new KeyValuePair<string, int>("scrap", 0);
            [JsonProperty("(0.3) How much HP is reduced when the portal is picked up (0-100)")]
            public float HP_Reduction = 0f;
            [JsonProperty("(0.4.0) Breakable portals")]
            public bool Breakable_Portals = false;
            [JsonProperty("(0.4.1) Total portal HP")]
            public int PortalHP = 250;
            [JsonProperty("(0.4.2) Portal Damage table (projectiles)")]
            public Dictionary<string, int> Portal_Damage_Table_Projectiles = new Dictionary<string, int>() {
                {
                    "riflebullet_explosive", 4
                }
                , {
                    "riflebullet", 0
                }
                , {
                    "pistolbullet", 0
                }
                ,
            }
            ;
            [JsonProperty("(0.4.3) Portal Damage table (explosives)")]
            public Dictionary<string, int> Portal_Damage_Table_Explosives = new Dictionary<string, int>() {
                {
                    "explosive.timed.deployed", 250
                }
                , {
                    "explosive.satchel.deployed", 70
                }
                , {
                    "rocket_basic", 220
                }
                , {
                    "40mm_grenade_he", 28
                }
            }
            ;
            [JsonProperty("(1) Portal Item Name")]
            public string PortalItemName = "Portal";
            [JsonProperty("(2) Portal Item ID")]
            public int PortalItemID = 198438816;
            [JsonProperty("(3) Portal Skin ID")]
            public ulong PortalSkinID = 2878854808;
            [JsonProperty("(4) Amount of portals /buyportal command gives")]
            public int AmountPerBuy = 1;
            [JsonProperty("(5) Display portal name")]
            public bool Display_Portal_Name = false;
            [JsonProperty("(6.1) Allow placing portals ONLY when player has building privilege")]
            public bool Allow_Placement_Only_In_Building_Privilege = false;
            [JsonProperty("(6.2) Allow picking up the portal only in building privilege")]
            public bool Allow_Pickup_Only_In_Building_Privilege = false;
            [JsonProperty("(6.3) Allow setting up the portal only in building privilege")]
            public bool Allow_Setting_Up_Only_In_Building_Privilege = false;
            [JsonProperty("(7.1) Enforce player portal limits")]
            public bool Enforce_Player_Portal_Limits = false;
            [JsonProperty("(7.2) Portal limits | Each entry in this list creates a permission (e.g.4 -> customportals.limit.4), grant this permission to players to enforce limits.")]
            public List<int> Portal_Limits = new List<int>() {
                4, 8, 12, 16
            }
            ;
            [JsonProperty("(7.3) Portal group list.You can specify as many as you want, they are not the same as Oxide groups.")]
            public string[] Groups = new string[] {
                "vip"
            }
            ;
            [JsonProperty("(7.4) Only allow players that are in the same group to use each other's portals")]
            public bool Allow_Only_In_The_Same_Group = false;
            [JsonProperty("(8.1) Allow players to enable broadcast on their portals (show portals on map)")]
            public bool Allow_Players_To_Enable_Broadcast = false;
            [JsonProperty("(8.2) Show monument portals on map")]
            public bool Show_Monument_Portals_On_Map = false;
            [JsonProperty("(9) Allow to link portals from 0 - everybody; 1 - only yourself; 2 - only yourself and teammates")]
            public int AllowLinkingFrom = 0;
            [JsonProperty("[NoEscape] Block portal if the player is combat blocked")]
            public bool Disable_If_Combat_Blocked = false;
            [JsonProperty("[NoEscape] Block portal if the player is raid blocked")]
            public bool Disable_If_Raid_Blocked = false;
            [JsonProperty("[Clans] Restrict portal usage only to clan members")]
            public bool Restrict_To_Clans_Members = false;
            [JsonProperty("[Clans] Restrict portal usage only to clan members and allies")]
            public bool Restrict_To_Clans_Members_And_Allies = false;
        }
#endregion
#region Configuration Boilerplate
        static Configuration config;
        private class SerializableConfiguration {
            public string ToJson() => JsonConvert.SerializeObject(this);
            public Dictionary<string, object> ToDictionary() => JsonHelper.Deserialize(ToJson()) as Dictionary<string, object>;
        }
        private static class JsonHelper {
            public static object Deserialize(string json) => ToObject(JToken.Parse(json));
            private static object ToObject(JToken token) {
                switch (token.Type) {
                    case JTokenType.Object : return token.Children<JProperty>().ToDictionary(prop => prop.Name, prop => ToObject(prop.Value));
                    case JTokenType.Array : return token.Select(ToObject).ToList();
                    default : return ((JValue)token).Value;
                }
            }
        }
        private bool ValidateConfig(Dictionary<string, object> currentWithDefaults, Dictionary<string, object> currentRaw) {
            var changed = false;
            var oldKeys = new List<string>();
            foreach (var key in currentRaw.Keys) {
                if (currentWithDefaults.Keys.Contains(key)) {
                    continue;
                }
                changed = true;
                oldKeys.Add(key);
            }
            foreach (var key in oldKeys) {
                currentRaw.Remove(key);
            }
            foreach (var key in currentWithDefaults.Keys) {
                object currentRawValue;
                if (currentRaw.TryGetValue(key, out currentRawValue)) {
                    var defaultDictValue = currentWithDefaults[key] as Dictionary<string, object>;
                    var currentDictValue = currentRawValue as Dictionary<string, object>;
                    if (defaultDictValue != null) {
                        if (currentDictValue == null) {
                            currentRaw[key] = currentWithDefaults[key];
                            changed = true;
                            continue;
                        }
                        if (ValidateConfig(defaultDictValue, currentDictValue)) {
                            changed = true;
                        }
                    }
                    continue;
                }
                currentRaw[key] = currentWithDefaults[key];
                changed = true;
            }
            return changed;
        }
        protected override void LoadDefaultConfig() => config = new Configuration();
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) {
                    throw new JsonException();
                }
                var currentWithDefaults = config.ToDictionary();
                var currentRaw = Config.ToDictionary(x => x.Key, x => x.Value);
                if (ValidateConfig(currentWithDefaults, currentRaw)) {
                    PrintWarning("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
            }
            catch {
                PrintWarning($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() {
            Puts($"Configuration changes saved to {Name}.json");
            Config.WriteObject(config, true);
        }
#endregion
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["portalGiven"]
                = "Portal has been given to you", ["alreadyLinked"] = "Portals with this name are already linked", ["noPerms"] = "You don't have permission to use this command", ["notEnoughPoints"] = "You don't have enough points to buy the portal", ["notEnoughResources"] = "You don't have enough {0} to buy the portal", ["uiInfoText"] = "Portals with the same name will link with each other", ["uiHeader"] = "RENAME PORTAL", ["changeBtnText"] = "CHANGE NAME", ["cancelBtnText"] = "CANCEL", ["noMonument"] = "You are not on a monument", ["adminCommandUsage"] = "<size=15>Usage:</size>\n/customportals add <portal name> - adds portal to the monument\n/customportals remove - removes portal from the monument\n/customportals reset - removes all portals from the monument", ["lookAtSurface"] = "Look at the surface you want to spawn on", ["addedToMonument"] = "Portal with the name \"{0}\" has been added to {1}", ["removedFromMonument"] = "Removed from {0}", ["lookAtPortal"] = "Make sure you are looking directly at the portal", ["allRemoved"] = "Wiped all data for {0}", ["cannotUse"] = "You can't use this portal", ["setPerm"] = "SET PERMISSION", ["uiAdminInfoText"] = "Set permission for this portal (admin only)", ["combatBlocked"] = "Can't use portals when combat blocked", ["raidBlocked"] = "Can't use portals when raid blocked", ["notInClan"] = "You are not in the same clan as the owner of the portal", ["notInClanOrAlliedClan"] = "You are not in the same or allied clan as the owner of the portal", ["notEnoughPointsToEnter"] = "You don't have enough points to use this portal", ["notEnoughResourcesToEnter"] = "You don't have enough {0} to use this portal", ["canPlaceOnlyInBuildingPrivilege"] = "You need to have building privilege to place portals", ["canSetupOnlyInBuildingPrivilege"] = "You need to have building privilege to setup this portal", ["limitExceeded"] = "You can't place more portals.You've exceeded your limit of {0} portals", ["broadcastOn"] = "ENABLE BROADCAST", ["broadcastOff"] = "DISABLE BROADCAST", ["cantLinkToOthersPortal"] = "Can't link to that portal", ["notInSameGroup"] = "You need to be in the same group as the portal owner in order to use it",
            }
            , this, "en");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["portalGiven"]
                = "Вам был выдан портал", ["alreadyLinked"] = "Порталы с таким названием уже соединены", ["noPerms"] = "У вас нет доступа к этой команде", ["notEnoughPoints"] = "Вам не хватает очков для покупки портала", ["notEnoughResources"] = "Вам не хватает {0} для покупки портала", ["uiInfoText"] = "Порталы с одинаковым названием будут соединены", ["uiHeader"] = "ПЕРЕИМЕНОВАТЬ", ["changeBtnText"] = "ПЕРЕИМЕНОВАТЬ", ["cancelBtnText"] = "ОТМЕНА", ["noMonument"] = "Вы не на РТ", ["adminCommandUsage"] = "<size=15>Использование:</size>\n/customportals add <название портала> - добавить портал на РТ\n/customportals remove - удалить портал с РТ\n/customportals reset - удалить все порталы с РТ", ["lookAtSurface"] = "Смотрите на поверхность на которой хотите заспаунить портал", ["addedToMonument"] = "Портал с названием \"{0}\" был добавлен на {1}", ["removedFromMonument"] = "Удалён с {0}", ["lookAtPortal"] = "Убедитесь, что смотрите на портал", ["allRemoved"] = "Вся информация {0} очищена!", ["cannotUse"] = "Вы не можете использовать этот портал", ["setPerm"] = "SET PERMISSION", ["uiAdminInfoText"] = "Настройте разрешения именно для этого портала", ["combatBlocked"] = "Нельзя использовать порталы в комбат-блоке", ["raidBlocked"] = "Нельзя использовать порталы в рейд-блоке", ["notInClan"] = "Вы не являетесь членом клана владельца портала", ["notInClanOrAlliedClan"] = "Вы не являетесь членом или союзником клана владельца портала", ["notEnoughPointsToEnter"] = "У вас не хватает валюты для использования этого портала", ["notEnoughResourcesToEnter"] = "Вам не хватает {0} для использования этого портала", ["canPlaceOnlyInBuildingPrivilege"] = "Ставить порталы можно только когда есть привилегия строительства", ["canSetupOnlyInBuildingPrivilege"] = "У вас должна быть привилегия строительства чтобы настроить этот портал", ["limitExceeded"] = "Вы больше не можете ставить порталы.Ваш лимит - {0}", ["broadcastOn"] = "ПОКАЗЫВАТЬ МЕСТОПОЛОЖЕНИЕ", ["broadcastOff"] = "СКРЫВАТЬ МЕСТОПОЛОЖЕНИЕ", ["cantLinkToOthersPortal"] = "Нельзя привязать к этому порталу", ["notInSameGroup"] = "Вам нужно быть в одной и той же группе, что и владелец портала, чтобы его использовать"
            }
            , this, "ru");
        }
        static string GetText(string textName, BasePlayer player) => Instance.lang.GetMessage(textName, Instance, player?.UserIDString);
#endregion
#region Fields
        public static CustomPortals Instance;
        static Dictionary<BasePlayer, string> PortalNameBuffer;
        static Dictionary<BasePlayer, string> PortalPermissionBuffer;
        static Dictionary<BasePortal, CustomPortalComponent> CustomPortalsDict;
        static Dictionary<BasePlayer, CustomPortalComponent> PlayersCurrentlyRenamingPortals;
        static Dictionary<MonumentInfo, List<CustomPortalComponent>> MonumentPortals;
        static Dictionary<string, List<PositionData>> CustomMapPortals;
        static List<BaseNetworkable> ToRemove;
        static List<BasePlayer> PlayersWithHealthBarShowed;
        static DataFileSystem dataFiles;
#endregion
#region Types
        public struct Price {
            public string ShortName;
            public int Amount;
            public ulong SkinID;
            public Price(string ShortName, int Amount, ulong SkinID) {
                this.ShortName = ShortName;
                this.Amount = Amount;
                this.SkinID = SkinID;
            }
            public bool TryPaying(BasePlayer player, string bypass_permission, string noPointsText, string noResourcesText) {
                var normalizedName = ShortName.ToLower();
                if ((normalizedName == "serverrewards" || normalizedName == "economics") && !CheckDependencyAndPrintWarning(normalizedName, player)) {
                    return false;
                }
                if (!Instance.permission.UserHasPermission(player.UserIDString, bypass_permission) && Amount > 0) {
                    switch (normalizedName) {
                        case "serverrewards" : var points = CheckPoints(player.userID);
                        if (points == null || points < Amount) {
                            Instance.PrintToChat(player, noPointsText);
                            return false;
                        }
                        TakePoints(player.userID, Amount);
                        break;
                        case "economics" : if (Economics_Withdraw(player.UserIDString, Amount) == false) {
                            Instance.PrintToChat(player, noPointsText);
                            return false;
                        }
                        break;
                        default : var itemDef = ItemManager.FindItemDefinition(ShortName);
                        if (SkinID != 0) {
                            var playerItems = Pool.GetList<Item>();
                            var itemsToCollect = Pool.GetList<Item>();
                            player.inventory.AllItemsNoAlloc(ref playerItems);
                            foreach (var item in playerItems) {
                                if (item.skin == SkinID && item.info.shortname == ShortName && item.amount > 0) {
                                    itemsToCollect.Add(item);
                                }
                            }
                            if (itemsToCollect.Count < Amount) {
                                Instance.PrintToChat(player, string.Format(noResourcesText, itemDef.displayName.english.ToLower()));
                                return false;
                            }
                            foreach (var item in itemsToCollect) {
                                item.RemoveFromContainer();
                            }
                            Pool.FreeList(ref itemsToCollect);
                            Pool.FreeList(ref playerItems);
                            break;
                        }
                        if (player.inventory.GetAmount(itemDef.itemid) < Amount) {
                            Instance.PrintToChat(player, string.Format(noResourcesText, itemDef.displayName.english.ToLower()));
                            return false;
                        }
                        player.inventory.Take(null, itemDef.itemid, Amount);
                        break;
                    }
                }
                return true;
            }
        }
        public class CustomPortalComponent : FacepunchBehaviour {
            public static CustomPortalComponent Spawn(Vector3 position, Quaternion rotation, string name = "Unnamed", bool isManuallyPlaced = false, string placedBy = "", string portalPermission = "", bool broadcastEnabled = false, BasePlayer placedByPlayer = null, float itemCondition = 100f, string ownerGroup = "", bool placedByAdmin = false) {
                var portal = GameManager.server.CreateEntity(PORTAL_PREFAB, position, rotation);
                portal.Spawn();
                if (placedBy != "") {
                    portal.OwnerID = Convert.ToUInt64(placedBy);
                }
                portal.EnableSaving(false);
                var comp = portal.gameObject.AddComponent<CustomPortalComponent>();
                comp.IsManuallyPlaced = isManuallyPlaced;
                comp.PlacedBy = placedBy;
                comp.PortalPermission = portalPermission;
                comp.ItemCondition = itemCondition;
                comp.OwnerGroup = ownerGroup;
                if (name != "Unnamed") {
                    comp.SetPortalName(name, placedByPlayer);
                }
                comp.SetBroadcastEnabled(broadcastEnabled);
                return comp;
            }
            public static Item CreateItem(int amount = 1, float condition = 100f) {
                var item = ItemManager.CreateByItemID(config.PortalItemID, amount, config.PortalSkinID);
                item.name = config.PortalItemName;
                item.condition = condition;
                return item;
            }
            public string PortalName {
                get {
                    return _portalName;
                }
                private set {
                    _portalName = value;
                    if (_vendingMarker != null && !_vendingMarker.IsDestroyed) {
                        _vendingMarker.markerShopName = "Portal - " + value;
                        _vendingMarker.SendNetworkUpdateImmediate();
                    }
                }
            }
            public string PortalPermission {
                get {
                    return _permission;
                }
                set {
                    _permission = value.Trim();
                    if (value != "" && !Instance.permission.PermissionExists($"{Instance.Name.ToLower()}.portal.{value}", Instance)) {
                        Instance.permission.RegisterPermission($"{Instance.Name.ToLower()}.portal.{value}", Instance);
                    }
                }
            }
            public CustomPortalComponent LinkedPortal {
                get;
                private set;
            }
            public bool IsManuallyPlaced {
                get;
                private set;
            }
            public bool IsPlacedByAdmin {
                get;
                private set;
            }
            public string PlacedBy {
                get;
                private set;
            }
            public string OwnerGroup {
                get;
                private set;
            }
            public bool IsBroadcastEnabled {
                get;
                private set;
            }
            public float ItemCondition {
                get;
                private set;
            }
            public int HP {
                get;
                private set;
            }
            MapMarkerGenericRadius _marker;
            VendingMachineMapMarker _vendingMarker;
            BasePortal _portal;
            string _permission;
            string _portalName;
            public BasePortal GetEntity() => _portal;
            public void Kill() => _portal.AdminKill();
            void Awake() {
                _portal = GetComponent<BasePortal>();
                PortalName = "Unnamed";
                HP = config.PortalHP;
                CustomPortalsDict.Add(_portal, this);
                if (config.Display_Portal_Name) {
                    InvokeRepeating(UpdateNameText, 0f, 1f);
                }
                if (config.Breakable_Portals) {
                    InvokeRepeating(CheckAndShowHealthbarRoutine, 0f, 0.5f);
                }
            }
            void OnDestroy() {
                DisableBroadcast();
                CancelInvoke(UpdateNameText);
                CancelInvoke(CheckAndShowHealthbarRoutine);
                CheckAndShowHealthbarRoutine();
                CustomPortalsDict?.Remove(_portal);
            }
            public object OnPlayerEnter(BasePlayer player) {
                if (!Instance.permission.UserHasPermission(player.UserIDString, PORTAL_USE_PERMISSION) || (_permission != "" && !Instance.permission.UserHasPermission(player.UserIDString, $"{Instance.Name.ToLower()}.portal.{PortalPermission}"))) {
                    Instance.PrintToChat(player, GetText("cannotUse", player));
                    return false;
                }
                if (!PlayerHasPortalGroup(player, OwnerGroup) && config.Allow_Only_In_The_Same_Group) {
                    Instance.PrintToChat(player, GetText("notInSameGroup", player));
                    return false;
                }
                if (config.Disable_If_Combat_Blocked && IsCombatBlocked(player.UserIDString) == true) {
                    Instance.PrintToChat(player, GetText("combatBlocked", player));
                    return false;
                }
                if (config.Disable_If_Raid_Blocked && IsRaidBlocked(player.UserIDString) == true) {
                    Instance.PrintToChat(player, GetText("raidBlocked", player));
                    return false;
                }
                if (PlacedBy != "" && player.UserIDString != PlacedBy) {
                    if (config.Restrict_To_Clans_Members && IsClanMember(player.UserIDString, PlacedBy) == false) {
                        Instance.PrintToChat(player, GetText("notInClan", player));
                        return false;
                    }
                    if (config.Restrict_To_Clans_Members_And_Allies && IsMemberOrAlly(player.UserIDString, PlacedBy) == false) {
                        Instance.PrintToChat(player, GetText("notInClanOrAlliedClan", player));
                        return false;
                    }
                }
                var activeItem = player.GetActiveItem();
                if (((!IsPlacedByAdmin && IsManuallyPlaced && ((!config.Allow_Pickup_Only_In_Building_Privilege && !player.IsBuildingBlocked()) || (config.Allow_Pickup_Only_In_Building_Privilege && player.IsBuildingAuthed()))) || (IsPlacedByAdmin && IsManuallyPlaced && player.IsAdmin)) && (activeItem != null && activeItem.info.itemid == HAMMER_ITEMID)) {
                    player.GiveItem(CreateItem(1, ItemCondition - config.HP_Reduction), BaseEntity.GiveItemReason.PickedUp);
                    _portal.AdminKill();
                    return false;
                }
                if (LinkedPortal == null && IsManuallyPlaced) {
                    if (!((!config.Allow_Setting_Up_Only_In_Building_Privilege && !player.IsBuildingBlocked()) || (config.Allow_Setting_Up_Only_In_Building_Privilege && player.IsBuildingAuthed()))) {
                        player.ShowToast(GameTip.Styles.Red_Normal, GetText("canSetupOnlyInBuildingPrivilege", player));
                        return false;
                    }
                    StartSettingUpPortal(player);
                    return false;
                }
                if (!config.PricePerEntry.TryPaying(player, PORTAL_FREE_ENTRY_PERMISSION, GetText("notEnoughPointsToEnter", player), GetText("notEnoughResourcesToEnter", player))) {
                    return false;
                }
                return null;
            }
            public void StartSettingUpPortal(BasePlayer player) {
                if (PlayersCurrentlyRenamingPortals.ContainsKey(player)) {
                    PlayersCurrentlyRenamingPortals[player] = this;
                }
                else {
                    PlayersCurrentlyRenamingPortals.Add(player, this);
                }
                ShowRenamingUI(player, PortalName, config.Allow_Players_To_Enable_Broadcast, IsBroadcastEnabled);
#if DEBUG
                ShowDebugUI(player, this);
#endif
                if (Instance.permission.UserHasPermission(player.UserIDString, ADMIN_PERMISSION)) {
                    ShowAdminUI(player, PortalPermission);
                }
            }
            public void TakeDamage(int damage) {
                if (!IsManuallyPlaced) {
                    return;
                }
                if (!config.Breakable_Portals) {
                    return;
                }
                if ((HP - damage) <= 0) {
                    Kill();
                    return;
                }
                HP -= damage;
            }
            public bool SetPortalName(string newName, BasePlayer changedBy = null) {
                CustomPortalComponent portalWithTheSameName = null;
                var count = 0;
                foreach (var portal in CustomPortalsDict.Values) {
                    if (portal == this) {
                        continue;
                    }
                    if (portal.PortalName != newName || portal.PortalName == "Unnamed") {
                        continue;
                    }
                    portalWithTheSameName = portal;
                    count++;
                }
                if (count >= 2) {
                    Instance.PrintWarning($"Trying to rename a portal to \"{newName}\", but there are more than 2 portals with that name!");
                    return false;
                }
                var otherPortalOwnerID = portalWithTheSameName?.PlacedBy;
                if (otherPortalOwnerID != null && changedBy != null && config.AllowLinkingFrom > 0 && otherPortalOwnerID != "" && !Instance.permission.UserHasPermission(changedBy.UserIDString, PORTAL_BYPASS_LINKING_LIMITATIONS)) {
                    var isOk = false;
                    switch (config.AllowLinkingFrom) {
                        case 1 : isOk = otherPortalOwnerID == PlacedBy;
                        break;
                        case 2 : isOk = otherPortalOwnerID == PlacedBy;
                        if (changedBy?.Team?.members == null) {
                            isOk = true;
                            break;
                        }
                        foreach (var teammateId in changedBy.Team.members) {
                            if (teammateId.ToString() != otherPortalOwnerID) {
                                continue;
                            }
                            isOk = true;
                            break;
                        }
                        break;
                    }
                    if (!isOk) {
                        ShowRenamingErrorUI(changedBy, GetText("cantLinkToOthersPortal", changedBy));
                        return false;
                    }
                }
                PortalName = newName;
                if (count == 1) {
                    LinkPortal(portalWithTheSameName);
                }
                else {
                    Unlink();
                }
                return true;
            }
            public void Unlink() {
                if (LinkedPortal == null) {
                    return;
                }
                LinkedPortal._portal.targetPortal = null;
                LinkedPortal._portal.LinkPortal();
                LinkedPortal.LinkedPortal = null;
                _portal.targetPortal = null;
                _portal.LinkPortal();
                LinkedPortal = null;
            }
            public void LinkPortal(CustomPortalComponent portalToLinkTo) {
                if (portalToLinkTo?._portal?.net == null) {
                    return;
                }
                LinkedPortal = portalToLinkTo;
                LinkedPortal.LinkedPortal = this;
                _portal.targetPortal = LinkedPortal._portal;
                LinkedPortal._portal.targetPortal = _portal;
                _portal.isUsablePortal = true;
                LinkedPortal._portal.isUsablePortal = true;
                _portal.LinkPortal();
                LinkedPortal._portal.LinkPortal();
                _portal.SendNetworkUpdateImmediate();
                LinkedPortal._portal.SendNetworkUpdateImmediate();
            }
            public void SetBroadcastEnabled(bool isEnabled) {
                if (isEnabled) {
                    EnableBroadcast();
                }
                else {
                    DisableBroadcast();
                }
            }
            public void ToggleBroadcast() {
                if (IsBroadcastEnabled) {
                    DisableBroadcast();
                }
                else {
                    EnableBroadcast();
                }
            }
            void CheckAndShowHealthbarRoutine() {
                var visPlayers = Pool.GetList<BasePlayer>();
                var visAndRaycastedPlayers = Pool.GetList<BasePlayer>();
                Vis.Entities(_portal.transform.position, 2f, visPlayers);
                foreach (var player in visPlayers) {
                    RaycastHit hit;
                    if (Physics.Raycast(player.eyes.position, player.eyes.HeadForward(), out hit, 2f, OBSTRUCTION_MASK)) {
                        var ent = hit.GetEntity();
                        if (ent == _portal.GetEntity()) {
                            visAndRaycastedPlayers.Add(player);
                        }
                    }
                }
                Pool.FreeList(ref visPlayers);
                foreach (var player in PlayersWithHealthBarShowed.ToArray()) {
                    if (!visAndRaycastedPlayers.Contains(player)) {
                        CuiHelper.DestroyUi(player, HP_BAR_CUI_NAME);
                        PlayersWithHealthBarShowed.Remove(player);
                    }
                }
                foreach (var player in visAndRaycastedPlayers) {
                    ShowHealthbar(player, HP, config.PortalHP);
                    if (!PlayersWithHealthBarShowed.Contains(player)) {
                        PlayersWithHealthBarShowed.Add(player);
                    }
                }
                Pool.FreeList(ref visAndRaycastedPlayers);
            }
            void EnableBroadcast() {
                if (_marker != null && !_marker.IsDestroyed) {
                    return;
                }
                _marker = GameManager.server.CreateEntity(RADIUS_MAP_MARKER_PREFAB, transform.position) as MapMarkerGenericRadius;
                _marker.alpha = 1f;
                _marker.color1 = Color.magenta;
                _marker.color2 = Color.white;
                _marker.radius = 0.1f;
                _marker.Spawn();
                _marker.SendUpdate();
                _marker.EnableSaving(false);
                _vendingMarker = GameManager.server.CreateEntity(VENDING_MAP_MARKER_PREFAB, transform.position) as VendingMachineMapMarker;
                _vendingMarker.markerShopName = "Portal - " + PortalName;
                _vendingMarker.Spawn();
                _vendingMarker.EnableSaving(false);
                IsBroadcastEnabled = true;
            }
            void DisableBroadcast() {
                IsBroadcastEnabled = false;
                _marker?.Kill();
                _vendingMarker?.Kill();
                _vendingMarker = null;
                _marker = null;
            }
            void UpdateNameText() {
                var players = Pool.GetList<BasePlayer>();
                Vis.Entities(transform.position, 5f, players, PLAYER_LAYER_MASK, QueryTriggerInteraction.Ignore);
                foreach (var player in players) {
                    if (player.IsNpc || player.IPlayer == null) {
                        continue;
                    }
                    if (Physics.Raycast(player.eyes.HeadRay(), player.Distance(transform.position), OBSTRUCTION_MASK, QueryTriggerInteraction.Ignore)) {
                        continue;
                    }
                    var wasAdmin = player.IsAdmin;
                    if (!wasAdmin) {
                        player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
                        player.SendNetworkUpdateImmediate();
                    }
                    player.SendConsoleCommand("ddraw.text", 1f, Color.cyan, transform.position + (Vector3.up * 1.5f), PortalName);
                    if (!wasAdmin) {
                        player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
                        player.SendNetworkUpdateImmediate();
                    }
                }
                Pool.FreeList(ref players);
            }
        }
#endregion
#region Oxide Hooks
        void Init() {
            Instance = this;
            dataFiles = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\{Name}");
            CustomPortalsDict = new Dictionary<BasePortal, CustomPortalComponent>();
            PortalNameBuffer = new Dictionary<BasePlayer, string>();
            PortalPermissionBuffer = new Dictionary<BasePlayer, string>();
            CustomMapPortals = new Dictionary<string, List<PositionData>>();
            ToRemove = new List<BaseNetworkable>();
            PlayersCurrentlyRenamingPortals = new Dictionary<BasePlayer, CustomPortalComponent>();
            PlayersWithHealthBarShowed = new List<BasePlayer>();
            MonumentPortals = new Dictionary<MonumentInfo, List<CustomPortalComponent>>();
            permission.RegisterPermission(ADMIN_PERMISSION, this);
            permission.RegisterPermission(PORTAL_BUY_PERMISSION, this);
            permission.RegisterPermission(PORTAL_FREE_PERMISSION, this);
            permission.RegisterPermission(PORTAL_USE_PERMISSION, this);
            permission.RegisterPermission(PORTAL_FREE_ENTRY_PERMISSION, this);
            permission.RegisterPermission(PORTAL_LIMIT_BYPASS_PERMISSION, this);
            permission.RegisterPermission(PORTAL_BYPASS_LINKING_LIMITATIONS, this);
            permission.RegisterPermission(PORTAL_SPAWN_PERMISSION, this);
            foreach (var groupName in config.Groups) {
                permission.RegisterPermission(PERMISSION_GROUP_PREFIX + groupName, this);
            }
            if (config.Breakable_Portals) {
                Subscribe(nameof(OnEntityTakeDamage));
            }
            else {
                Unsubscribe(nameof(OnEntityTakeDamage));
            }
#if DEBUG
            PrintWarning("Plugin is in DEBUG mode!");
#endif
        }
        void Loaded() {
            foreach (var limit in config.Portal_Limits) {
                var perm = $"customportals.limit.{limit}";
                if (permission.PermissionExists(perm, this)) {
                    continue;
                }
                permission.RegisterPermission(perm, this);
            }
        }
        void Unload() {
            SavePlayerData();
            CacheCustomMapData();
            foreach (var player in PlayersWithHealthBarShowed) {
                CuiHelper.DestroyUi(player, HP_BAR_CUI_NAME);
            }
            foreach (var portal in CustomPortalsDict.Values) {
                portal.Kill();
            }
        }
        void OnServerInitialized(bool initial) {
            PortalDataLoader.Instantiate().BeginLoadingData(initial);
        }
        void OnServerSave() => SavePlayerData();
        void OnNewSave(string filename) {
            PrintWarning("Server wiped! Clearing portal data...");
            ClearPlayerData();
            ClearCustomMapCache();
        }
        object OnPortalUse(BasePlayer player, BasePortal portal) {
            if (portal is XmasDungeon) {
                return null;
            }
            if (!CustomPortalsDict.ContainsKey(portal)) {
                return null;
            }
            return CustomPortalsDict[portal].OnPlayerEnter(player);
        }
        object CanBuild(Planner plan, Construction prefab, Construction.Target target) {
            if (plan == null) {
                return null;
            }
            var item = plan.GetItem();
            if (item == null) {
                return null;
            }
            var player = plan.GetOwnerPlayer();
            if (player == null) {
                return null;
            }
            if (!(item.info.itemid == config.PortalItemID && item.skin == config.PortalSkinID)) {
                return null;
            }
            if (config.Enforce_Player_Portal_Limits && !permission.UserHasPermission(player.UserIDString, PORTAL_LIMIT_BYPASS_PERMISSION)) {
                var playerPortals = 0;
                foreach (var portal in CustomPortalsDict.Values) {
                    if (portal.PlacedBy != player.UserIDString) {
                        continue;
                    }
                    playerPortals++;
                }
                var playerLimit = -1;
                foreach (var perm in permission.GetUserPermissions(player.UserIDString)) {
                    if (!perm.StartsWith("customportals.limit.")) {
                        continue;
                    }
                    var limit = Convert.ToInt32(perm.Split('.')[2]);
                    if (playerLimit < limit) {
                        playerLimit = limit;
                    }
                }
                if (playerLimit != -1 && playerPortals >= playerLimit) {
                    player.ShowToast(GameTip.Styles.Red_Normal, string.Format(GetText("limitExceeded", player), playerLimit));
                    return false;
                }
            }
            if (config.Allow_Placement_Only_In_Building_Privilege && !player.IsBuildingAuthed()) {
                player.ShowToast(GameTip.Styles.Red_Normal, GetText("canPlaceOnlyInBuildingPrivilege", player));
                return false;
            }
            return null;
        }
        void OnEntityBuilt(Planner plan, GameObject go) {
            if (plan == null) {
                return;
            }
            var item = plan.GetItem();
            if (item == null) {
                return;
            }
            var player = plan.GetOwnerPlayer();
            if (player == null) {
                return;
            }
            if (item.info.itemid == config.PortalItemID && item.skin == config.PortalSkinID) {
                var portal = CustomPortalComponent.Spawn(go.transform.position - PORTAL_PLACEMENT_OFFSET, go.transform.rotation, isManuallyPlaced : true, placedBy : player.UserIDString, placedByPlayer : player, itemCondition : item.condition, ownerGroup : GetPortalGroup(player));
                NextFrame(() => {
                    go.GetComponent<BaseEntity>().AdminKill();
                }
                );
            }
        }
        void OnWorldPrefabSpawned(GameObject gameObject, string category) {
            if (!category.ToLower().Contains("customportals")) {
                return;
            }
            try {
                var portalName = category.ToLower().Split('.')[1].Split(':')[0].ToLower().Trim();
                var ent = gameObject.GetComponent<BaseNetworkable>();
                var posData = new PositionData(gameObject.transform.position, gameObject.transform.rotation);
                if (!CustomMapPortals.ContainsKey(portalName)) {
                    CustomMapPortals.Add(portalName, new List<PositionData>());
                }
                CustomMapPortals[portalName].Add(posData);
                ToRemove.Add(ent);
            }
            catch {
                PrintWarning($"Portal name \"{category}\" is invalid!");
            }
        }
        object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
            if (!(entity as BasePortal)) {
                return null;
            }
            CustomPortalComponent comp;
            if (CustomPortalsDict.TryGetValue(entity as BasePortal, out comp)) {
                if (info?.WeaponPrefab?.ShortPrefabName != null && config.Portal_Damage_Table_Explosives.ContainsKey(info.WeaponPrefab.ShortPrefabName)) {
                    comp.TakeDamage(config.Portal_Damage_Table_Explosives[info.WeaponPrefab.ShortPrefabName]);
                    return null;
                }
                if (info?.ProjectilePrefab?.name != null && config.Portal_Damage_Table_Projectiles.ContainsKey(info.ProjectilePrefab.name)) {
                    comp.TakeDamage(config.Portal_Damage_Table_Projectiles[info.ProjectilePrefab.name]);
                    return null;
                }
            }
            return null;
        }
#endregion
#region UI
        public static void ShowRenamingUI(BasePlayer player, string initialName, bool showBroadcastBtn, bool isBroadcastEnabled = false) {
            var elements = new CuiElementContainer();
            elements.Add(new CuiElement {
                Name = RENAMING_CUI_NAME, Parent = "Overlay", Components = {
                    new CuiNeedsCursorComponent(), new CuiNeedsKeyboardComponent(), new CuiImageComponent {
                        Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat", Sprite = "assets/content/ui/ui.background.transparent.radial.psd", Color = "0.1286 0.1808 0.1512 0.954"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            elements.Add(new CuiElement {
                Name = RENAMING_CUI_NAME + "_textboxPanel", Parent = RENAMING_CUI_NAME, Components = {
                    new CuiImage
// ... [Code preview truncated due to length. Full source in attached file] ...

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