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

FREE AbandonedBases : 2.1.2 2.1.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6

/*
*  <----- End-User License Agreement ----->
*  
*  You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of This Software without the Developer’s consent
*  
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
*  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*
*  Developer: nivex (mswenson82@yahoo.com)
*
*  Copyright © 2022-2023 nivex
*/
using Facepunch;
using Facepunch.Math;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Plugins.AbandonedBasesExtensionMethods;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Abandoned Bases", "nivex", "2.1.2")]
    [Description("Allows bases to become raidable when the owner becomes inactive")]
    public class AbandonedBases : RustPlugin {
#region Variables
        [PluginReference]
        Plugin Backpacks, Economics, ServerRewards, IQEconomic, RaidableBases, Clans, Friends, Notify, AdvancedAlerts, ZoneManager, SkillTree;
        private new const string Name = "Abandoned Bases";
        private List<string> ID_FLOORS = new() {
            "floor", "floor.frame", "floor.grill", "floor.ladder.hatch", "floor.triangle", "floor.triangle.frame", "floor.triangle.grill", "floor.triangle.ladder.hatch"
        }
        ;
        private List<string> ID_DQD = new() {
            "foundation", "foundation.triangle", "roof.triangle", "roof"
        }
        ;
        private List<string> TrueDamage = new() {
            "Barricade", "SimpleBuildingBlock", "IceFence", "TeslaCoil", "BaseTrap", "GunTrap", "FlameTurret", "FogMachine", "SamSite", "AutoTurret"
        }
        ;
        private Coroutine reportCoroutine;
        private bool isLoaded {
            get;
            set;
        }
        private bool DebugMode {
            get;
            set;
        }
        private bool newSave {
            get;
            set;
        }
        private bool IsPurgeEnabled {
            get;
            set;
        }
        private StoredData data {
            get;
            set;
        }
        = new();
        private StringBuilder _sb {
            get;
            set;
        }
        = new();
        private Coroutine abandonedCoroutine {
            get;
            set;
        }
        private List<ulong> AbandonedSleepers {
            get;
            set;
        }
        = new();
        private List<string> _waitingList {
            get;
            set;
        }
        = new();
        private List<UserConversion> _conversions {
            get;
            set;
        }
        = new();
        private List<AbandonedBuilding> AbandonedBuildings {
            get;
            set;
        }
        = new();
        private Dictionary<ulong, DelaySettings> PvpDelay {
            get;
            set;
        }
        = new();
        private Dictionary<ulong, List<Notification>> _notifications {
            get;
            set;
        }
        = new();
        private Dictionary<ulong, AbandonedBuilding> AbandonedReferences {
            get;
            set;
        }
        = new();
        public class UserConversion {
            public string userid;
            public Coroutine co;
            public List<ulong> owners;
            public UserConversion(string userid, List<ulong> owners, Coroutine co) {
                this.owners = owners;
                this.userid = userid;
                this.co = co;
            }
            public bool Exists(IPlayer user, List<ulong> owners) {
                if (co == null) {
                    return false;
                }
                return userid == user.Id || this.owners.Exists(owners.Contains);
            }
        }
        public class Notification {
            public BasePlayer player;
            public string messageEx;
        }
        private class StoredData {
            [JsonProperty("Last Seen", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, int> LastSeen {
                get;
                set;
            }
            = new();
            [JsonProperty("Cooldown Between Conversion", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, DateTime> CooldownBetweenConversion {
                get;
                set;
            }
            = new();
            [JsonProperty("Cooldown Between Cancel", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, DateTime> CooldownBetweenCancel {
                get;
                set;
            }
            = new();
            [JsonProperty("Cooldown Between Events", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, DateTime> CooldownBetweenEvents {
                get;
                set;
            }
            = new();
            [JsonProperty("Activities", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ActivityInfo> Activity {
                get;
                set;
            }
            = new();
            public string LastRunTime {
                get;
                set;
            }
            = DateTime.MinValue.ToString();
            public int protocol = 243;
            public StoredData() {
            }
        }
        public class Payment {
            public Payment(BasePlayer player, double cost = 0, List<CustomCostOptions> options = null) {
                userId = player.userID;
                this.options = options;
                this.player = player;
                this.cost = cost;
            }
            public double cost {
                get;
                set;
            }
            public ulong userId {
                get;
                set;
            }
            public List<CustomCostOptions> options {
                get;
                set;
            }
            public BasePlayer player {
                get;
                set;
            }
        }
        internal class ActivityInfo {
            [JsonProperty(PropertyName = "owners", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ulong> owners {
                get;
                set;
            }
            = new();
            [JsonProperty(PropertyName = "permission")]
            public string perm {
                get;
                set;
            }
            = string.Empty;
            [JsonProperty(PropertyName = "total")]
            public int total {
                get;
                set;
            }
            internal ActivityInfo() {
            }
            public bool SameOwners(List<ulong> owners) => owners.All(this.owners.Contains);
            internal int GetLimit(Configuration config) {
                if (string.IsNullOrEmpty(perm) || !perm.PermissionExists() || !owners.Exists(owner => owner.HasPermission(perm))) {
                    SetPermission(config);
                }
                foreach (var purge in config.Purges) {
                    if (perm == purge.Permission) {
                        return purge.NoPurge ? 0 : purge.Limit;
                    }
                }
                return 0;
            }
            internal void SetPermission(Configuration config) {
                var limit = int.MinValue;
                foreach (var owner in this.owners) {
                    var purge = PurgeSettings.Find(config, owner);
                    if (purge == null || string.IsNullOrEmpty(purge.Permission)) {
                        continue;
                    }
                    if (purge.Limit > limit) {
                        perm = purge.Permission;
                        limit = purge.Limit;
                    }
                    if (purge.Limit <= 0) {
                        perm = purge.Permission;
                        break;
                    }
                }
            }
        }
        internal class DelaySettings {
            internal AbandonedBuilding Building {
                get;
                set;
            }
            public Timer Timer {
                get;
                set;
            }
            public void Destroy() {
                if (Timer != null && !Timer.Destroyed) {
                    Timer.Callback();
                    Timer.Destroy();
                }
            }
        }
        internal class AbandonedBuilding : FacepunchBehaviour {
            internal class EntityOwner {
                public BaseEntity Entity;
                public ulong OwnerID;
                public EntityOwner(BaseEntity entity) {
                    Entity = entity;
                    OwnerID = entity.OwnerID;
                }
            }
            internal class Raider {
                public ulong userid;
                public string username;
                public bool IsParticipant;
                public bool HasEntered;
                public Raider(BasePlayer target) {
                    userid = target.userID;
                    username = target.displayName;
                }
            }
            internal List<ulong> IsAllowed {
                get;
                set;
            }
            = new();
            internal List<ulong> Messages {
                get;
                set;
            }
            = new();
            internal HashSet<uint> buildingIDs {
                get;
                set;
            }
            = new();
            internal List<BuildingPrivlidge> privs {
                get;
                set;
            }
            = new();
            internal List<ulong> owners {
                get;
                set;
            }
            = new();
            internal List<BaseEntity> entities {
                get;
                set;
            }
            = new();
            internal List<SphereEntity> spheres {
                get;
                set;
            }
            = new();
            internal List<Vector3> compound {
                get;
                set;
            }
            = new();
            internal List<Vector3> foundations {
                get;
                set;
            }
            = new();
            internal List<BasePlayer> intruders {
                get;
                set;
            }
            = new();
            internal Dictionary<ulong, Raider> raiders {
                get;
                set;
            }
            = new();
            internal List<StorageContainer> containers {
                get;
                set;
            }
            = new();
            internal Dictionary<ulong, EntityOwner> EntityOwners {
                get;
                set;
            }
            = new();
            internal MapMarkerGenericRadius genericMarker = null;
            internal VendingMachineMapMarker vendingMarker = null;
            internal bool IsOwnerLocked {
                get;
                set;
            }
            internal bool IsDamaged {
                get;
                set;
            }
            internal bool DisableEventCooldown {
                get;
                set;
            }
            internal PluginTimers timer {
                get;
                set;
            }
            internal BaseEntity anchor {
                get;
                set;
            }
            internal DateTime DespawnDateTime {
                get;
                set;
            }
            internal float radius {
                get;
                set;
            }
            internal bool AutomatedEvent {
                get;
                set;
            }
            internal bool markerCreated {
                get;
                set;
            }
            internal bool isDestroyed {
                get;
                set;
            }
            internal bool IsClaimed {
                get;
                set;
            }
            internal bool AllowPVP {
                get;
                set;
            }
            internal bool IsExpired {
                get;
                set;
            }
            internal SphereCollider _collider {
                get;
                set;
            }
            internal Payment payment {
                get;
                set;
            }
            internal List<string> groups {
                get;
                set;
            }
            = new();
            internal GameObject go {
                get;
                set;
            }
            internal float cancelCooldownTime {
                get;
                set;
            }
            internal bool isCanceled {
                get;
                set;
            }
            internal string raiderName {
                get;
                set;
            }
            internal ulong raiderId {
                get;
                set;
            }
            internal string currentName {
                get;
                set;
            }
            internal ulong currentId {
                get;
                set;
            }
            internal string previousName {
                get;
                set;
            }
            internal ulong previousId {
                get;
                set;
            }
            internal bool canReassign {
                get;
                set;
            }
            = true;
            internal ActivityInfo activity {
                get;
                set;
            }
            internal int lootAmount {
                get;
                set;
            }
            internal Coroutine _coroutine {
                get;
                set;
            }
            internal AbandonedBases Instance {
                get;
                set;
            }
            internal bool LockBaseToFirstAttacker => AllowPVP ? config.Abandoned.LockBaseToFirstAttackerPVP : config.Abandoned.LockBaseToFirstAttackerPVE;
            internal bool EjectFromLockedBase;
            internal string GetGrid() => PhoneController.PositionToGridCoord(center);
            internal Vector3 _center {
                get;
                set;
            }
            private Configuration config => Instance.config;
            private StoredData data => Instance.data;
            public bool HasEventCooldown(BasePlayer player) => Instance.HasEventCooldown(player, this);
            public bool HasCooldown(BasePlayer player, string perm) => Instance.HasCooldown(player, perm, data.CooldownBetweenEvents);
            public void Message(BasePlayer player, string key, params object[] args) => Instance.Message(player, key, args);
            public void LogToFile(string filename, string text) => Instance.LogToFile(filename, text, Instance, false, true);
            internal Vector3 center {
                get {
                    if (!anchor.IsKilled()) {
                        _center = anchor.transform.position;
                    }
                    return _center;
                }
                set {
                    _center = value;
                }
            }
            public bool InRange(Vector3 from) => AbandonedBases.InRange(from, center, radius);
            public bool NearCompound(Vector3 from) => compound.Exists(to => AbandonedBases.InRange(from, to, 3f));
            public bool NearFoundation(Vector3 from) => foundations.Exists(to => AbandonedBases.InRange(from, to, 3f));
            public Raider GetRaider(BasePlayer player) {
                if (!raiders.TryGetValue(player.userID, out var ri)) {
                    raiders[player.userID] = ri = new(player);
                }
                return ri;
            }
            public static bool AddRange(AbandonedBases m, List<BaseEntity> entities, List<StorageContainer> containers, List<Vector3> foundations, List<Vector3> compound, List<Vector3> walls, IPlayer user, ulong userid) {
                var floors = new List<Vector3>();
                foreach (var e in entities.ToList()) {
                    if (e.IsKilled()) {
                        entities.Remove(e);
                        continue;
                    }
                    if (e.ShortPrefabName == "foundation" || e.ShortPrefabName == "foundation.triangle" || e.skinID == 1337424001 && e is CollectibleEntity) {
                        if (m.config.Abandoned.Twig || e is BuildingBlock block && block.grade != BuildingGrade.Enum.Twigs) {
                            foundations.Add(e.transform.position);
                            compound.Add(e.transform.position);
                        }
                    }
                    else if (e.ShortPrefabName.Contains("external.high")) {
                        compound.Add(e.transform.position);
                    }
                    else if (e.ShortPrefabName == "wall" || e.ShortPrefabName == "wall.half" || e.ShortPrefabName == "wall.window") {
                        if (m.config.Abandoned.Twig || e is BuildingBlock block && block.grade != BuildingGrade.Enum.Twigs) {
                            walls.Add(e.transform.position);
                        }
                    }
                    else if (m.ID_FLOORS.Contains(e.ShortPrefabName)) {
                        floors.Add(e.transform.position);
                    }
                    else if (IsBox(e) || e is BuildingPrivlidge) {
                        containers.Add(e as StorageContainer);
                    }
                }
                if (foundations.Count == 0 || foundations.Count < m.config.Abandoned.FoundationLimit || walls.Count < m.config.Abandoned.WallLimit) {
                    return m.IsPurgeEnabled && m.config.Abandoned.DespawnSecondsInactive <= 0f && user == null && !m.CanPurge(userid, Epoch.Current);
                    // allow when auto converting bases that are built during purge
                }
                return true;
            }
            public static bool AddRange(AbandonedBases m, List<BaseEntity> entities, List<StorageContainer> containers, List<Vector3> compound, ref int loot) {
                List<BaseEntity.Slot> _checkSlots = new() {
                    BaseEntity.Slot.Lock, BaseEntity.Slot.UpperModifier, BaseEntity.Slot.MiddleModifier, BaseEntity.Slot.LowerModifier
                }
                ;
                foreach (var e in entities.ToList()) {
                    if (e.IsKilled()) {
                        entities.Remove(e);
                        continue;
                    }
                    if (IsBox(e) || e is BuildingPrivlidge) {
                        containers.Add(e as StorageContainer);
                    }
                    foreach (var checkSlot in _checkSlots) {
                        var slot = e.GetSlot(checkSlot);
                        if (slot == null) continue;
                        if (entities.Contains(slot)) continue;
                        entities.Add(slot);
                    }
                    var container = e as IItemContainerEntity;
                    if (container?.inventory?.itemList != null) {
                        loot += container.inventory.itemList.Count;
                    }
                    compound.Add(e.transform.position);
                }
                return m.config.Abandoned.Tugboats.Loot <= 0 || loot >= m.config.Abandoned.Tugboats.Loot;
            }
            public void TrySetOwner(IPlayer user) {
                if (user == null || user.IsServer) {
                    return;
                }
                var player = user.Object as BasePlayer;
                if (!player || player.IsFlying || player.limitNetworking) {
                    return;
                }
                SetOwner(player.userID, player.displayName, player.userID, player.displayName);
            }
            public void TrySetOwnerLock(BasePlayer attacker) {
                if (IsOwnerLocked && !CanBypass(attacker) && !IsAlly(attacker)) {
                    TryEjectFromLockedBase(attacker);
                    return;
                }
                if (!attacker.IsHuman() || HasEventCooldown(attacker)) {
                    return;
                }
                GetRaider(attacker).IsParticipant = true;
                if (owners.Contains(attacker.userID) || IsAlly(attacker)) {
                    return;
                }
                if (string.IsNullOrEmpty(raiderName)) {
                    raiderName = attacker.displayName;
                    raiderId = attacker.userID;
                }
                if (canReassign && LockBaseToFirstAttacker) {
                    IsOwnerLocked = true;
                    canReassign = false;
                    SetOwner(attacker.userID, attacker.displayName, currentId, currentName);
                    Invoke(UpdateMarkers, 0f);
                }
            }
            public bool CanBypass(BasePlayer player) {
                return !player.IsHuman() || player.IsFlying || player.limitNetworking || player.HasPermission("abandonedbases.canbypass");
            }
            public bool IsOwner(BasePlayer player) {
                return owners.Contains(player.userID) || CanBypass(player) || IsAlly(player);
            }
            public void SetOwner(ulong newid, string newname, ulong currid, string currname) {
                previousName = currname;
                previousId = currid;
                currentName = newname;
                currentId = newid;
            }
            public void TryEjectFromLockedBase(BasePlayer player) {
                if (!EjectFromLockedBase || !IsOwnerLocked || owners.Contains(player.userID)) {
                    return;
                }
                if (anchor == null && !NearFoundation(player.transform.position)) {
                    return;
                }
                if (anchor is Tugboat && !(player.GetParentEntity() is Tugboat)) {
                    return;
                }
                RemovePlayer(player);
            }
            public void RemovePlayer(BasePlayer player) {
                var m = player.GetMounted();
                if (m != null) {
                    m.DismountPlayer(player, true);
                }
                if (player.HasParent()) {
                    player.SetParent(null);
                }
                var position = GetEjectLocation(player.transform.position, 10f, center, radius);
                player.Teleport(player.IsFlying ? position.WithY(player.transform.position.y) : position);
                player.SendNetworkUpdateImmediate();
                intruders.Remove(player);
            }
            public static Vector3 GetEjectLocation(Vector3 a, float distance, Vector3 target, float radius) {
                var position = ((a.XZ3D() - target.XZ3D()).normalized * (radius + distance)) + target;
                // credits ZoneManager
                float y = TerrainMeta.HighestPoint.y + 250f;
                if (Physics.Raycast(position + new Vector3(0f, y, 0f), Vector3.down, out var hit, Mathf.Infinity, 10551313, QueryTriggerInteraction.Ignore)) {
                    position.y = hit.point.y + 0.75f;
                }
                else position.y = Mathf.Max(TerrainMeta.HeightMap.GetHeight(position), TerrainMeta.WaterMap.GetHeight(position)) + 0.75f;
                return position;
            }
            public void TryMessage(BasePlayer player, string key, params object[] args) {
                if (Messages.Contains(player.userID)) return;
                ulong userid = player.userID;
                Messages.Add(userid);
                timer.Once(10f, () => Messages.Remove(userid));
                Message(player, key, args);
            }
            public void Setup(AbandonedBases m, IPlayer user, PluginTimers timer, List<Vector3> compound, List<Vector3> foundations, List<BaseEntity> entities, List<StorageContainer> containers, List<ulong> owners, Vector3 center, Payment payment, float radius, bool allowPVP, bool isAutomated) {
                Instance = m;
                TrySetOwner(user);
                AutomatedEvent = isAutomated;
                markerCreated = user == null && !config.Abandoned.AutoMarkers || user != null && !config.Abandoned.ManualMarkers;
                canReassign = currentId == 0 || string.IsNullOrEmpty(currentName);
                EjectFromLockedBase = allowPVP ? config.Abandoned.EjectLockedPVP : config.Abandoned.EjectLockedPVE;
                this.Instance.AbandonedBuildings.Add(this);
                this.AllowPVP = allowPVP;
                this.compound = compound;
                this.foundations = foundations;
                this.containers = containers;
                this.entities = entities;
                this.payment = payment;
                this.owners = owners;
                this.radius = radius;
                this.timer = timer;
                this.center = center;
                Interface.Oxide.NextTick(() => {
                    TryInvokeMethod(SetupEntities);
                    TryInvokeMethod(SetupCollider);
                    TryInvokeMethod(CompleteConvertPayment);
                    TryInvokeMethod(Announce);
                    TryInvokeMethod(InvokeDespawnInactive);
                    TryInvokeMethod(SpawnNpcs);
                    TryInvokeMethod(SetupSleepers);
                    UpdateActivity(owners);
                    cancelCooldownTime = Time.time + config.Abandoned.CancelCooldown;
                }
                );
                Interface.CallHook("OnAbandonedBaseStarted", center, AllowPVP, intruders, entities);
            }
            private void Awake() {
                go = gameObject;
            }
            private float fixedProtectorTime;
            private void FixedUpdate() {
                if (EjectFromLockedBase) {
                    fixedProtectorTime += Time.fixedDeltaTime;
                    if (fixedProtectorTime >= 1f) {
                        fixedProtectorTime = float.MinValue;
                        Protector();
                        fixedProtectorTime = 0f;
                    }
                }
            }
            private void OnDestroy() {
                if (groups.Count > 0) {
                    Plugin BotReSpawn = Interface.Oxide.RootPluginManager.GetPlugin("BotReSpawn");
                    groups.ForEach(group => BotReSpawn?.Call("RemoveGroupSpawn", group));
                }
            }
            private bool IsAlly(BasePlayer player) => Instance.IsAlly(player.userID, currentId);
            private void Protector() {
                if (isDestroyed || !IsOwnerLocked || intruders.Count == 0) {
                    return;
                }
                foreach (var intruder in intruders.ToList()) {
                    if (intruder.IsKilled()) {
                        intruders.Remove(intruder);
                        continue;
                    }
                    if (IsAllowed.Contains(intruder.userID)) {
                        continue;
                    }
                    if (IsOwner(intruder)) {
                        IsAllowed.Add(intruder.userID);
                        continue;
                    }
                    TryEjectFromLockedBase(intruder);
                }
            }
            private void OnTriggerEnter(Collider collider) {
                if (collider == null) {
                    return;
                }
                var entity = collider.ToBaseEntity();
                if (entity is BasePlayer player) {
                    if (!intruders.Contains(player)) {
                        intruders.Add(player);
                        GetRaider(player).HasEntered = true;
                        Message(player, AllowPVP ? "OnPlayerEntered" : "OnPlayerEnteredPVE");
                        Interface.CallHook("OnPlayerEnteredAbandonedBase", player, transform.position, AllowPVP, center, intruders, entities);
                    }
                }
                else if (entity is BaseMountable m) {
                    GetMountedPlayers(m).ForEach(player => {
                        if (!intruders.Contains(player)) {
                            intruders.Add(player);
                            GetRaider(player).HasEntered = true;
                            Message(player, AllowPVP ? "OnPlayerEntered" : "OnPlayerEnteredPVE");
                            Interface.CallHook("OnPlayerEnteredAbandonedBase", player, center, AllowPVP, intruders, entities);
                        }
                    }
                    );
                }
            }
            private void OnTriggerExit(Collider collider) {
                if (collider == null) {
                    return;
                }
                var entity = collider.ToBaseEntity();
                if (entity is BasePlayer player) {
                    OnPlayerExit(player, player.IsDead());
                }
                else if (entity is BaseMountable m) {
                    GetMountedPlayers(m).ForEach(player => OnPlayerExit(player, player.IsDead()));
                }
            }
            public void DestroyMe() {
                isDestroyed = true;
                TryInvokeMethod(CancelEntitySetup);
                TryInvokeMethod(KillMarkers);
                TryInvokeMethod(KillSpheres);
                TryInvokeMethod(RewardPlayers);
                TryInvokeMethod(PowerDownAutoTurrets);
                TryInvokeMethod(RestoreEntityOwners);
                TryInvokeMethod(RemoveReferences);
                TryInvokeMethod(CancelInvokes);
                if (anchor.IsKilled()) Destroy(go);
                Destroy(this);
            }
            private void SetupSleepers() {
                if (!config.KillInactiveSleepers || !config.MoveInventory) {
                    return;
                }
                var boxes = containers.Where(x => !x.IsKilled() && IsBox(x) && !x.inventory.IsFull());
                if (boxes.Count == 0) {
                    return;
                }
                foreach (var entity in entities) {
                    if (entity.IsKilled() || entity is not BasePlayer target) continue;
                    if (!target.IsSleeping() || target.IsConnected || target.inventory == null) continue;
                    var items = target.inventory.AllItems().ToList();
                    while (items.Count > 0 && boxes.Count > 0) {
                        var box = boxes.GetRandom();
                        if (box.inventory.IsFull()) {
                            boxes.Remove(box);
                            continue;
                        }
                        Item item = items[0];
                        items.Remove(item);
                        if (item == null) {
                            continue;
                        }
                        if (config.MoveInventoryBlacklist.Contains(item.info.shortname) || !item.MoveToContainer(box.inventory)) {
                            item.RemoveFromContainer();
                            item.Remove(0f);
                        }
                    }
                }
            }
            public void RewardPlayers() {
                if (IsClaimed) {
                    return;
                }
                var participants = intruders.Where(IsPlayerEligible);
                foreach (var player in participants) {
                    if (!isCanceled) {
                        Instance.GiveRewards(player, participants.Count);
                    }
                    if (!DisableEventCooldown) {
                        SetEventCooldown(player.userID);
                    }
                }
                if (isCanceled || Instance.IsUnloading) {
                    return;
                }
                var activeId = raiderId == 0uL ? currentId : raiderId;
                var activeName = string.IsNullOrEmpty(raiderName) ? currentName : raiderName;
                var players = string.Join(", ", participants.Select(x => x.displayName));
                var text = $"{activeName ?? "UNKNOWN"} ({activeId}) has raided the base with {players} participating at {center} ({GetGrid()}) owned by {previousName ?? "UNKNOWN"} ({previousId})";
                if (participants.Count == 0) text = $"{activeName ?? "UNKNOWN"} ({activeId}) base has been abandoned at {center} ({GetGrid()}) by {previousName ?? "UNKNOWN"} ({previousId})";
                if (config.UseLogFile && activeName != previousName) {
                    LogToFile("sar", text);
                }
                Puts(text);
            }
            private bool IsPlayerEligible(BasePlayer player) {
                return !(player == null || player.IsFlying || player.limitNetworking || config.Abandoned.RemoveAdminRaiders && player.IsAdmin || !GetRaider(player).IsParticipant || HasCooldown(player, "abandonedbases.noeventcooldown"));
            }
            private void RestoreEntityOwners() {
                if (IsExpired || IsClaimed || EntityOwners.Count == 0) {
                    return;
                }
                foreach (var pair in EntityOwners.ToList()) {
                    if (pair.Value.Entity.IsKilled()) continue;
                    pair.Value.Entity.OwnerID = pair.Value.OwnerID;
                }
            }
            private void RemoveReferences() => Instance.RemoveReferences(this, entities);
            private void CancelInvokes() {
                try {
                    CancelInvoke(DestroyAll);
                }
                catch {
                }
            }
            public void KillMarkers() {
                vendingMarker.SafelyKill();
                genericMarker.SafelyKill();
            }
            public void KillSpheres() {
                spheres.ToList().ForEach(sphere => sphere.SafelyKill());
            }
            public void KillCollider() {
                if (_collider != null) {
                    DestroyImmediate(_collider);
                }
            }
            private void CompleteConvertPayment() => CompletePayment(payment, false);
            public void CompleteCancelPayment(Payment payment) => CompletePayment(payment, true);
            public void SetConversionCooldown(ulong userid) {
                if (!Instance.IgnoreConversionCooldowns() && config.Abandoned.CooldownBetweenConversion > 0 && !userid.HasPermission("abandonedbases.convert.nocooldown")) {
                    data.CooldownBetweenConversion[userid] = DateTime.Now.AddSeconds(config.Abandoned.CooldownBetweenConversion);
                }
            }
            public void SetCancelCooldown(ulong userid) {
                if (!Instance.IgnoreCancelCooldowns() && config.Abandoned.CooldownBetweenCancel > 0 && !userid.HasPermission("abandonedbases.convert.cancel.nocooldown")) {
                    data.CooldownBetweenCancel[userid] = DateTime.Now.AddSeconds(config.Abandoned.CooldownBetweenCancel);
                }
            }
            public void SetEventCooldown(ulong userid) {
                if (!Instance.IgnoreEventCooldowns() && config.Abandoned.CooldownBetweenEvents > 0 && !userid.HasPermission("abandonedbases.noeventcooldown")) {
                    data.CooldownBetweenEvents[userid] = DateTime.Now.AddSeconds(config.Abandoned.CooldownBetweenEvents);
                }
            }
            private void CompletePayment(Payment payment, bool cancel) {
                if (cancel) {
                    isCanceled = config.Abandoned.Rewards.Cancel;
                }
                if (payment == null || payment.cost == 0 && !payment.options.IsValid()) {
                    return;
                }
                var eco = cancel ? config.Abandoned.EconomicsCancel : config.Abandoned.Economics;
                if (eco > 0 && Instance.Economics.CanCall()) {
                    if (Convert.ToBoolean(Instance.Economics?.Call("Withdraw", payment.userId.ToString(), payment.cost))) {
                        if (payment.player.IsValid()) {
                            Message(payment.player, cancel ? "EconomicsWithdrawCancel" : "EconomicsWithdraw", payment.cost);
                        }
                    }
                }
                var rp = cancel ? config.Abandoned.ServerRewardsCancel : config.Abandoned.ServerRewards;
                if (rp > 0 && Instance.ServerRewards.CanCall()) {
                    if (Convert.ToBoolean(Instance.ServerRewards?.Call("TakePoints", payment.userId, (int)payment.cost))) {
                        if (payment.player.IsValid()) {
                            Message(payment.player, cancel ? "ServerRewardPointsTakenCancel" : "ServerRewardPointsTaken", (int)payment.cost);
                        }
                    }
                }
                if (payment.options.IsValid()) {
                    TakeCustomCost(payment.player, payment.options, cancel);
                }
            }
            private void TakeCustomCost(BasePlayer player, List<CustomCostOptions> options, bool cancel) {
                var sb = new StringBuilder();
                foreach (var option in options) {
                    if (option.Amount <= 0) continue;
                    var slots = player.inventory.FindItemsByItemID(option.Definition.itemid);
                    var amountLeft = option.Amount;
                    foreach (var slot in slots) {
                        if (slot == null || option.Skin != 0 && slot.skin != option.Skin) {
                            continue;
                        }
                        var taken = slot.amount > amountLeft ? slot.SplitItem(amountLeft) : slot;
                        if (taken == null) {
                            continue;
                        }
                        taken.RemoveFromContainer();
                        taken.Remove(0f);
                        amountLeft -= taken.amount;
                        if (amountLeft <= 0) {
                            string name = string.IsNullOrEmpty(option.Name) ? slot.info.displayName.english : option.Name;
                            sb.Append(string.Format("{0} {1}", option.Amount, name)).Append(", ");
                            break;
                        }
                    }
                }
                if (sb.Length > 2) {
                    sb.Length -= 2;
                    Message(player, cancel ? "CustomCostTakenCancel" : "CustomCostTaken", sb.ToString());
                }
            }
            public void Announce() {
                if (Instance.IsPurgeEnabled) {
                    return;
                }
                var grid = GetGrid();
                foreach (var target in BasePlayer.activePlayerList) {
                    if (target.HasPermission("abandonedbases.notices")) {
                        Message(target, "Abandoned", grid);
                    }
                }
            }
            public bool IsAttached(BaseEntity entity) {
                if (NearCompound(entity.transform.position)) {
                    return true;
                }
                if (entity is DecayEntity decayEntity && buildingIDs.Contains(decayEntity.buildingID)) {
                    return true;
                }
                if (entity.GetBuildingPrivilege() is BuildingPrivlidge priv && buildingIDs.Contains(priv.buildingID)) {
                    return true;
                }
                return false;
            }
            public void RememberOwner(BaseEntity entity) {
                if (entity.OwnerID == 0 || owners.Contains(entity.OwnerID)) {
                    Instance.AbandonedReferences[entity.net.ID.Value] = this;
                    EntityOwners[entity.net.ID.Value] = new(entity);
                    var ice = entity as IItemContainerEntity;
                    if (ice == null || ice.inventory == null) return;
                    lootAmount += ice.inventory.itemList.Count;
                }
            }
            private void CancelEntitySetup() {
                Interface.CallHook("OnAbandonedBaseEnded", center, AllowPVP, intruders, entities);
                if (_coroutine != null) {
                    ServerMgr.Instance.StopCoroutine(_coroutine);
                    _coroutine = null;
                }
            }
            private IEnumerator EntitySetup() {
                float invokeTime = 0f;
                int checks = 0;
                foreach (var e in entities.ToList()) {
                    if (++checks % 100 == 0) {
                        yield return CoroutineEx.waitForSeconds(0.025f);
                    }
                    if (e.IsKilled() || e.net == null || e.OwnerID == 0 && e is StorageContainer || e.OwnerID != 0 && !owners.Contains(e.OwnerID)) {
                        entities.Remove(e);
                        continue;
                    }
                    RememberOwner(e);
                    if (e is BuildingPrivlidge priv) SetCurrentNameFromBuilding(priv);
                    if (e is Tugboat) SetCurrentNameFromVehicle(e);
                    if (e is DecayEntity decayEntity) SetupDecayEntity(decayEntity);
                    if (e is AutoTurret turret) Instance.timer.Once(invokeTime += 0.1f, () => SetupTurret(turret));
                    if (config.Abandoned.DespawnSecondsInactive <= 0f && !config.RemoveOwnershipZero) continue;
                    if (config.RemoveOwnership || config.RemoveOwnershipFromContainers && e is StorageContainer) e.OwnerID = 0;
                }
                var type = anchor.IsKilled() ? "BUILDING" : $"{anchor.GetType().Name.ToUpper()}";
                if (!string.IsNullOrEmpty(previousName)) {
                    Puts("{0} - {1} ({2}) at {3} with {4} entities and {5} items", type, previousName, previousId, center, entities.Count, lootAmount);
                }
                else Puts("{0} - {1} with {2} entities and {3} items", type, center, entities.Count, lootAmount);
                _coroutine = null;
            }
            private void SetCurrentNameFromBuilding(BuildingPrivlidge priv) {
                if (!string.IsNullOrEmpty(currentName)) return;
                if (priv.OwnerID.IsSteamId() && owners.Contains(priv.OwnerID)) {
                    var username = GetUserName(priv.OwnerID);
                    SetOwner(priv.OwnerID, username, priv.OwnerID, username);
                }
                privs.Add(priv);
            }
            private void SetCurrentNameFromVehicle(BaseEntity entity) {
                if (!string.IsNullOrEmpty(currentName)) return;
                var priv = Instance.GetVehiclePrivilege(entity.children);
                if (priv == null || !priv.AnyAuthed()) return;
                foreach (var auth in priv.authorizedPlayers) {
                    var username = GetUserName(auth.userid);
                    if (string.IsNullOrEmpty(username)) continue;
                    SetOwner(auth.userid, username, auth.userid, username);
                    break;
                }
            }
            private void SetupEntities() {
                _coroutine = ServerMgr.Instance.StartCoroutine(EntitySetup());
                Instance.Subscribe();
            }
            private void SetupDecayEntity(DecayEntity e) {
                buildingIDs.Add(e.buildingID);
            }
            public class TurretInfo {
                public Item weapon;
                public AutoTurret turret;
                public List<Item> items = new();
            }
            private List<TurretInfo> turrets = new();
            private void SetupTurret(AutoTurret turret) {
                if (!config.Abandoned.AutoTurret.Enabled) {
                    return;
                }
                SetupIO(turret);
                turret.InitializeHealth(config.Abandoned.AutoTurret.Health, config.Abandoned.AutoTurret.Health);
                turret.sightRange = config.Abandoned.AutoTurret.SightRange;
                turret.aimCone = config.Abandoned.AutoTurret.AimCone;
                if (config.Abandoned.AutoTurret.RemoveWeapon) {
                    turret.AttachedWeapon = null;
                    Item slot = turret.inventory.GetSlot(0);
                    if (slot != null && (slot.info.category == ItemCategory.Weapon || slot.info.category == ItemCategory.Fun)) {
                        slot.RemoveFromContainer();
                        slot.Remove();
                    }
                }
                TurretInfo ti = new() {
                    turret = turret
                }
                ;
                if (config.Abandoned.AutoTurret.Shortnames.Count > 0) {
                    ActionIn(0.1f, () => {
                        if (!turret.IsKilled() && turret.AttachedWeapon == null) {
                            var shortname = config.Abandoned.AutoTurret.Shortnames.GetRandom();
                            var itemToCreate = ItemManager.FindItemDefinition(shortname);
                            if (itemToCreate != null) {
                                Item item = ItemManager.Create(itemToCreate, 1, (ulong)itemToCreate.skins.GetRandom().id);
                                if (!item.MoveToContainer(turret.inventory, 0, false)) {
                                    item.Remove();
                                }
                                else {
                                    item.SwitchOnOff(true);
                                    ti.weapon = item;
                                }
                            }
                        }
                    }
                    );
                }
                ActionIn(1f, turret.UpdateAttachedWeapon);
                ActionIn(2.5f, () => FillAmmoTurret(ti));
                if (config.Abandoned.AutoTurret.Hostile) {
                    turret.SetPeacekeepermode(false);
                }
                if (!config.Abandoned.AutoTurret.RequiresPower && !turret.IsOnline()) {
                    ActionIn(3f, turre
// ... [Code preview truncated due to length. Full source in attached file] ...

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