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

FREE VehicleLicence : 1.7.25 1.7.25

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
 // #define DEBUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Facepunch;
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Rust.Modular;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Vehicle Licence", "Sorrow/TheDoc/Arainrr", "1.7.25")]
    [Description("Allows players to buy vehicles and then spawn or store it")]
    public class VehicleLicence : RustPlugin {
#region Fields
        [PluginReference]
        private readonly Plugin Economics, ServerRewards, Friends, Clans, NoEscape, LandOnCargoShip, RustTranslationAPI;
        private const string PERMISSION_USE = "vehiclelicence.use";
        private const string PERMISSION_ALL = "vehiclelicence.all";
        private const string PERMISSION_ADMIN = "vehiclelicence.admin";
        private const string PERMISSION_BYPASS_COST = "vehiclelicence.bypasscost";
        private const int ITEMID_FUEL = -946369541;
        private const string PREFAB_ITEM_DROP = "assets/prefabs/misc/item drop/item_drop.prefab";
        private const string PREFAB_ROWBOAT = "assets/content/vehicles/boats/rowboat/rowboat.prefab";
        private const string PREFAB_RHIB = "assets/content/vehicles/boats/rhib/rhib.prefab";
        private const string PREFAB_SEDAN = "assets/content/vehicles/sedan_a/sedantest.entity.prefab";
        private const string PREFAB_HOTAIRBALLOON = "assets/prefabs/deployable/hot air balloon/hotairballoon.prefab";
        private const string PREFAB_MINICOPTER = "assets/content/vehicles/minicopter/minicopter.entity.prefab";
        private const string PREFAB_TRANSPORTCOPTER = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";
        private const string PREFAB_CHINOOK = "assets/prefabs/npc/ch47/ch47.entity.prefab";
        private const string PREFAB_RIDABLEHORSE = "assets/rust.ai/nextai/testridablehorse.prefab";
        private const string PREFAB_WORKCART = "assets/content/vehicles/workcart/workcart.entity.prefab";
        private const string PREFAB_MAGNET_CRANE = "assets/content/vehicles/crane_magnet/magnetcrane.entity.prefab";
        private const string PREFAB_SUBMARINE_DUO = "assets/content/vehicles/submarine/submarineduo.entity.prefab";
        private const string PREFAB_SUBMARINE_SOLO = "assets/content/vehicles/submarine/submarinesolo.entity.prefab";
        private const string PREFAB_CHASSIS_SMALL = "assets/content/vehicles/modularcar/car_chassis_2module.entity.prefab";
        private const string PREFAB_CHASSIS_MEDIUM = "assets/content/vehicles/modularcar/car_chassis_3module.entity.prefab";
        private const string PREFAB_CHASSIS_LARGE = "assets/content/vehicles/modularcar/car_chassis_4module.entity.prefab";
        private const string PREFAB_SNOWMOBILE = "assets/content/vehicles/snowmobiles/snowmobile.prefab";
        private const string PREFAB_SNOWMOBILE_TOMAHA = "assets/content/vehicles/snowmobiles/tomahasnowmobile.prefab";
        private const int LAYER_GROUND = Rust.Layers.Solid | Rust.Layers.Mask.Water;
        private static object False;
        private Timer _checkVehiclesTimer;
        public static VehicleLicence Instance {
            get;
            private set;
        }
        public readonly Dictionary<BaseEntity, Vehicle> vehiclesCache = new Dictionary<BaseEntity, Vehicle>();
        public readonly Dictionary<string, BaseVehicleS> allBaseVehicleSettings = new Dictionary<string, BaseVehicleS>();
        public readonly Dictionary<string, string> commandToVehicleType = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        public enum NormalVehicleType {
            Rowboat, RHIB, Sedan, HotAirBalloon, MiniCopter, TransportHelicopter, Chinook, RidableHorse, WorkCart, MagnetCrane, SubmarineSolo, SubmarineDuo, Snowmobile, TomahaSnowmobile,
        }
        public enum ChassisType {
            Small, Medium, Large
        }
#endregion Fields
#region Oxide Hooks
        private void Init() {
            LoadData();
            False = false;
            Instance = this;
            permission.RegisterPermission(PERMISSION_USE, this);
            permission.RegisterPermission(PERMISSION_ALL, this);
            permission.RegisterPermission(PERMISSION_ADMIN, this);
            permission.RegisterPermission(PERMISSION_BYPASS_COST, this);
            foreach (NormalVehicleType value in Enum.GetValues(typeof(NormalVehicleType))) {
                allBaseVehicleSettings.Add(value.ToString(), GetBaseVehicleS(value));
            }
            foreach (var entry in configData.modularCarS) {
                allBaseVehicleSettings.Add(entry.Key, entry.Value);
            }
            foreach (var entry in allBaseVehicleSettings) {
                var baseVehicleS = entry.Value;
                if (baseVehicleS.usePermission && !string.IsNullOrEmpty(baseVehicleS.permission) && !permission.PermissionExists(baseVehicleS.permission, this)) {
                    permission.RegisterPermission(baseVehicleS.permission, this);
                }
                foreach (var perm in baseVehicleS.cooldownPermissions.Keys) {
                    if (!permission.PermissionExists(perm, this)) {
                        permission.RegisterPermission(perm, this);
                    }
                }
                foreach (var command in baseVehicleS.commands) {
                    if (string.IsNullOrEmpty(command)) continue;
                    if (!commandToVehicleType.ContainsKey(command)) {
                        commandToVehicleType.Add(command, entry.Key);
                    }
                    else {
                        PrintError($"You have the same two commands({command}).");
                    }
                    if (configData.chatS.useUniversalCommand) {
                        cmd.AddChatCommand(command, this, nameof(CmdUniversal));
                    }
                    if (!string.IsNullOrEmpty(configData.chatS.customKillCommandPrefix)) {
                        cmd.AddChatCommand(configData.chatS.customKillCommandPrefix + command, this, nameof(CmdCustomKill));
                    }
                }
            }
            cmd.AddChatCommand(configData.chatS.helpCommand, this, nameof(CmdLicenseHelp));
            cmd.AddChatCommand(configData.chatS.buyCommand, this, nameof(CmdBuyVehicle));
            cmd.AddChatCommand(configData.chatS.spawnCommand, this, nameof(CmdSpawnVehicle));
            cmd.AddChatCommand(configData.chatS.recallCommand, this, nameof(CmdRecallVehicle));
            cmd.AddChatCommand(configData.chatS.killCommand, this, nameof(CmdKillVehicle));
            Unsubscribe(nameof(CanMountEntity));
            Unsubscribe(nameof(OnEntityTakeDamage));
            Unsubscribe(nameof(OnEntityDismounted));
            Unsubscribe(nameof(OnEntityEnter));
            Unsubscribe(nameof(CanLootEntity));
            Unsubscribe(nameof(OnEntitySpawned));
        }
        private void OnServerInitialized() {
            if (configData.globalS.storeVehicle) {
                var currentTimestamp = TimeEx.currentTimestamp;
                foreach (var vehicleEntries in storedData.playerData) {
                    foreach (var vehicleEntry in vehicleEntries.Value) {
                        vehicleEntry.Value.lastRecall = vehicleEntry.Value.lastDismount = currentTimestamp;
                        vehicleEntry.Value.playerID = vehicleEntries.Key;
                        vehicleEntry.Value.vehicleType = vehicleEntry.Key;
                        if (vehicleEntry.Value.entityID == 0) {
                            continue;
                        }
                        vehicleEntry.Value.entity = BaseNetworkable.serverEntities.Find(vehicleEntry.Value.entityID) as BaseEntity;
                        if (vehicleEntry.Value.entity == null || vehicleEntry.Value.entity.IsDestroyed) {
                            vehicleEntry.Value.entityID = 0;
                        }
                        else {
                            vehiclesCache.Add(vehicleEntry.Value.entity, vehicleEntry.Value);
                        }
                    }
                }
            }
            if (configData.globalS.preventMounting) {
                Subscribe(nameof(CanMountEntity));
            }
            if (configData.globalS.noDecay) {
                Subscribe(nameof(OnEntityTakeDamage));
            }
            if (configData.globalS.preventDamagePlayer) {
                Subscribe(nameof(OnEntityEnter));
            }
            if (configData.globalS.preventLooting) {
                Subscribe(nameof(CanLootEntity));
            }
            if (configData.globalS.autoClaimFromVendor) {
                Subscribe(nameof(OnEntitySpawned));
                Subscribe(nameof(OnRidableAnimalClaimed));
            }
            if (configData.globalS.checkVehiclesInterval > 0 && allBaseVehicleSettings.Any(x => x.Value.wipeTime > 0)) {
                Subscribe(nameof(OnEntityDismounted));
                _checkVehiclesTimer = timer.Every(configData.globalS.checkVehiclesInterval, CheckVehicles);
            }
        }
        private void Unload() {
            _checkVehiclesTimer?.Destroy();
            if (!configData.globalS.storeVehicle) {
                foreach (var entry in vehiclesCache.ToArray()) {
                    if (entry.Key != null && !entry.Key.IsDestroyed) {
                        RefundVehicleItems(entry.Value, entry.Key, isUnload : true);
                        entry.Key.Kill(BaseNetworkable.DestroyMode.Gib);
                    }
                    entry.Value.entityID = 0;
                }
            }
            SaveData();
            False = Instance = null;
        }
        private void OnServerSave() => timer.Once(UnityEngine.Random.Range(0f, 60f), SaveData);
        private void OnPlayerConnected(BasePlayer player) {
            if (player == null || !player.userID.IsSteamId()) return;
            if (permission.UserHasPermission(player.UserIDString, PERMISSION_BYPASS_COST)) {
                PurchaseAllVehicles(player.userID);
            }
        }
        private void OnEntityDismounted(BaseMountable entity, BasePlayer player) {
            var vehicleParent = entity?.VehicleParent();
            if (vehicleParent == null || vehicleParent.IsDestroyed) return;
            Vehicle vehicle;
            if (!vehiclesCache.TryGetValue(vehicleParent, out vehicle)) {
                return;
            }
            vehicle.OnDismount();
        }
#region Mount
        private object CanMountEntity(BasePlayer friend, BaseMountable entity) {
            if (friend == null || entity == null) return null;
            var vehicleParent = entity.VehicleParent();
            if (vehicleParent == null || vehicleParent.IsDestroyed) return null;
            Vehicle vehicle;
            if (!vehiclesCache.TryGetValue(vehicleParent, out vehicle)) return null;
            if (AreFriends(vehicle.playerID, friend.userID)) return null;
            if (configData.globalS.preventDriverSeat && vehicleParent.HasMountPoints()) {
                foreach (var allMountPoint in vehicleParent.allMountPoints) {
                    if (allMountPoint != null && allMountPoint.mountable == entity) {
                        if (!allMountPoint.isDriver) {
                            return null;
                        }
                        break;
                    }
                }
            }
            if (HasAdminPermission(friend)) {
                return null;
            }
            SendCantUseMessage(friend, vehicle);
            return False;
        }
#endregion Mount
#region Loot
        private object CanLootEntity(BasePlayer friend, StorageContainer container) {
            if (friend == null || container == null) return null;
            var parentEntity = container.GetParentEntity();
            if (parentEntity == null) return null;
            Vehicle vehicle;
            if (!vehiclesCache.TryGetValue(parentEntity, out vehicle)) {
                var vehicleParent = (parentEntity as BaseVehicleModule)?.Vehicle;
                if (vehicleParent == null || !vehiclesCache.TryGetValue(vehicleParent, out vehicle)) {
                    return null;
                }
            }
            if (AreFriends(vehicle.playerID, friend.userID)) {
                return null;
            }
            if (HasAdminPermission(friend)) {
                return null;
            }
            SendCantUseMessage(friend, vehicle);
            return False;
        }
#endregion Loot
#region Claime
        private void OnEntitySpawned(MotorRowboat motorRowboat) {
            NextFrame(() => {
                var player = motorRowboat?.creatorEntity as BasePlayer;
                if (player == null || !player.userID.IsSteamId() || !motorRowboat.OnlyOwnerAccessible()) return;
                TryClaimVehicle(player, motorRowboat, motorRowboat is RHIB ? NormalVehicleType.RHIB : NormalVehicleType.Rowboat);
            }
            );
        }
        private void OnEntitySpawned(MiniCopter miniCopter) {
            NextFrame(() => {
                var player = miniCopter?.creatorEntity as BasePlayer;
                if (player == null || !player.userID.IsSteamId() || !miniCopter.OnlyOwnerAccessible()) return;
                TryClaimVehicle(player, miniCopter, miniCopter is ScrapTransportHelicopter ? NormalVehicleType.TransportHelicopter : NormalVehicleType.MiniCopter);
            }
            );
        }
        private void OnRidableAnimalClaimed(BaseRidableAnimal baseRidableAnimal, BasePlayer player) {
            if (player == null || !player.userID.IsSteamId()) return;
            TryClaimVehicle(player, baseRidableAnimal, NormalVehicleType.RidableHorse);
        }
#endregion Claime
#region Decay
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo) {
            if (entity == null | hitInfo?.damageTypes == null) return;
            if (hitInfo.damageTypes.Has(Rust.DamageType.Decay)) {
                if (!vehiclesCache.ContainsKey(entity)) {
                    var vehicle = (entity as BaseVehicleModule)?.Vehicle;
                    if (vehicle == null || !vehiclesCache.ContainsKey(vehicle)) {
                        return;
                    }
                }
                hitInfo.damageTypes.Scale(Rust.DamageType.Decay, 0);
            }
        }
#endregion Decay
#region Damage
        // ScrapTransportHelicopter / ModularCar / TrainEngine / MagnetCrane
        private object OnEntityEnter(TriggerHurtNotChild triggerHurtNotChild, BasePlayer player) {
            if (triggerHurtNotChild == null || triggerHurtNotChild.SourceEntity == null || player == null) return null;
            var sourceEntity = triggerHurtNotChild.SourceEntity;
            if (vehiclesCache.ContainsKey(sourceEntity)) {
                var baseVehicle = sourceEntity as BaseVehicle;
                if (baseVehicle != null && player.userID.IsSteamId()) {
                    if (baseVehicle is TrainEngine) {
                        var transform = triggerHurtNotChild.transform;
                        MoveToPosition(player, transform.position + (UnityEngine.Random.value >= 0.5f ? -transform.right : transform.right) * 2.5f);
                        return False;
                    }
                    Vector3 pos;
                    if (GetDismountPosition(baseVehicle, player, out pos)) {
                        MoveToPosition(player, pos);
                    }
                }
                //triggerHurtNotChild.enabled = false;
                return False;
            }
            return null;
        }
        // HotAirBalloon
        private object OnEntityEnter(TriggerHurt triggerHurt, BasePlayer player) {
            if (triggerHurt == null || player == null) return null;
            var sourceEntity = triggerHurt.gameObject.ToBaseEntity();
            if (sourceEntity == null) return null;
            if (vehiclesCache.ContainsKey(sourceEntity)) {
                if (player.userID.IsSteamId()) {
                    MoveToPosition(player, sourceEntity.CenterPoint() + Vector3.down);
                }
                //triggerHurt.enabled = false;
                return False;
            }
            return null;
        }
#endregion Damage
#region Destroy
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) => CheckEntity(entity, true);
        private void OnEntityKill(BaseCombatEntity entity) => CheckEntity(entity);
#endregion Destroy
#endregion Oxide Hooks
#region Methods
#region Message
        private void SendCantUseMessage(BasePlayer friend, Vehicle vehicle) {
            var baseVehicleS = GetBaseVehicleS(vehicle.vehicleType);
            if (baseVehicleS != null) {
                var player = RustCore.FindPlayerById(vehicle.playerID);
                var playerName = player?.displayName ?? ServerMgr.Instance.persistance.GetPlayerName(vehicle.playerID) ?? "Unknown";
                Print(friend, Lang("CantUse", friend.UserIDString, baseVehicleS.displayName, $"<color=#{(player != null && player.IsConnected ? "69D214" : "FF6347")}>{playerName}</color>"));
            }
        }
#endregion Message
#region CheckEntity
        private void CheckEntity(BaseCombatEntity entity, bool isCrash = false) {
            if (entity == null) return;
            Vehicle vehicle;
            if (!vehiclesCache.TryGetValue(entity, out vehicle)) return;
            vehiclesCache.Remove(entity);
            vehicle.OnDeath();
            var baseVehicleS = GetBaseVehicleS(vehicle.vehicleType);
            RefundVehicleItems(vehicle, entity, isCrash : isCrash, baseVehicleS : baseVehicleS);
            if (isCrash && baseVehicleS.removeLicenseOnceCrash) {
                RemoveVehicleLicense(vehicle.playerID, vehicle.vehicleType);
            }
        }
#endregion CheckEntity
#region CheckVehicles
        private void CheckVehicles() {
            var currentTimestamp = TimeEx.currentTimestamp;
            foreach (var entry in vehiclesCache.ToArray()) {
                if (entry.Key == null || entry.Key.IsDestroyed) continue;
                if (VehicleIsActive(entry.Key, entry.Value, currentTimestamp)) continue;
                if (VehicleAnyMounted(entry.Key)) continue;
                entry.Key.Kill(BaseNetworkable.DestroyMode.Gib);
            }
        }
        private bool VehicleIsActive(BaseEntity entity, Vehicle vehicle, double currentTimestamp) {
            var baseVehicleS = GetBaseVehicleS(vehicle.vehicleType);
            if (baseVehicleS.wipeTime <= 0) return true;
            if (baseVehicleS.excludeCupboard && entity.GetBuildingPrivilege() != null) return true;
            return currentTimestamp - vehicle.lastDismount < baseVehicleS.wipeTime;
        }
#endregion CheckVehicles
#region Refund
        private static bool CanRefundFuel(BaseVehicleS baseVehicleS, bool isCrash, bool isUnload) {
            if (isUnload) return true;
            var fuelVehicleS = baseVehicleS as IFuelVehicle;
            return fuelVehicleS != null && (isCrash ? fuelVehicleS.refundFuelOnCrash : fuelVehicleS.refundFuelOnKill);
        }
        private static bool CanRefundInventory(BaseVehicleS baseVehicleS, bool isCrash, bool isUnload) {
            if (isUnload) return true;
            var inventoryVehicleS = baseVehicleS as IInventoryVehicle;
            return inventoryVehicleS != null && (isCrash ? inventoryVehicleS.refundInventoryOnCrash : inventoryVehicleS.refundInventoryOnKill);
        }
        private static void ModularCarRefundState(BaseVehicleS baseVehicleS, bool isCrash, bool isUnload, out bool refundFuel, out bool refundInventory, out bool refundEngine, out bool refundModule) {
            if (isUnload) {
                refundFuel = refundInventory = refundEngine = refundModule = true;
                return;
            }
            var modularVehicleS = baseVehicleS as ModularVehicleS;
            if (modularVehicleS == null) {
                refundFuel = refundInventory = refundEngine = refundModule = false;
                return;
            }
            refundFuel = isCrash ? modularVehicleS.refundFuelOnCrash : modularVehicleS.refundFuelOnKill;
            refundInventory = isCrash ? modularVehicleS.refundInventoryOnCrash : modularVehicleS.refundInventoryOnKill;
            refundEngine = isCrash ? modularVehicleS.refundEngineOnCrash : modularVehicleS.refundEngineOnKill;
            refundModule = isCrash ? modularVehicleS.refundModuleOnCrash : modularVehicleS.refundModuleOnKill;
        }
        private void RefundVehicleItems(Vehicle vehicle, BaseEntity entity, BaseVehicleS baseVehicleS = null, bool isCrash = false, bool isUnload = false) {
            if (entity == null) entity = vehicle.entity;
            if (entity == null) return;
            if (baseVehicleS == null) baseVehicleS = GetBaseVehicleS(vehicle.vehicleType);
            if (baseVehicleS == null) return;
            NormalVehicleType normalVehicleType;
            var collect = Pool.GetList<Item>();
            if (Enum.TryParse(vehicle.vehicleType, out normalVehicleType)) {
                ItemContainer inventory = null;
                EntityFuelSystem fuelSystem = null;
                switch (normalVehicleType) {
                    case NormalVehicleType.Sedan : case NormalVehicleType.Chinook : return;
                    case NormalVehicleType.MiniCopter : case NormalVehicleType.TransportHelicopter : {
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = (entity as MiniCopter)?.GetFuelSystem();
                        }
                    }
                    break;
                    case NormalVehicleType.HotAirBalloon : {
                        var hotAirBalloon = entity as HotAirBalloon;
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = hotAirBalloon?.fuelSystem;
                        }
                        if (CanRefundInventory(baseVehicleS, isCrash, isUnload)) {
                            inventory = (hotAirBalloon?.storageUnitInstance.Get(true) as StorageContainer)?.inventory;
                        }
                    }
                    break;
                    case NormalVehicleType.RHIB : case NormalVehicleType.Rowboat : {
                        var motorRowboat = entity as MotorRowboat;
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = motorRowboat?.GetFuelSystem();
                        }
                        if (CanRefundInventory(baseVehicleS, isCrash, isUnload)) {
                            inventory = (motorRowboat?.storageUnitInstance.Get(true) as StorageContainer)?.inventory;
                        }
                    }
                    break;
                    case NormalVehicleType.RidableHorse : {
                        if (CanRefundInventory(baseVehicleS, isCrash, isUnload)) {
                            inventory = (entity as RidableHorse)?.inventory;
                        }
                    }
                    break;
                    case NormalVehicleType.WorkCart : {
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = (entity as TrainEngine)?.GetFuelSystem();
                        }
                    }
                    break;
                    case NormalVehicleType.MagnetCrane : {
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = (entity as BaseCrane)?.GetFuelSystem();
                        }
                    }
                    break;
                    case NormalVehicleType.SubmarineSolo : case NormalVehicleType.SubmarineDuo : {
                        var baseSubmarine = entity as BaseSubmarine;
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = baseSubmarine?.GetFuelSystem();
                        }
                        if (CanRefundInventory(baseVehicleS, isCrash, isUnload)) {
                            inventory = baseSubmarine?.GetTorpedoContainer()?.inventory;
                        }
                    }
                    break;
                    case NormalVehicleType.Snowmobile : case NormalVehicleType.TomahaSnowmobile : {
                        var snowmobile = entity as Snowmobile;
                        if (CanRefundFuel(baseVehicleS, isCrash, isUnload)) {
                            fuelSystem = snowmobile?.GetFuelSystem();
                        }
                        if (CanRefundInventory(baseVehicleS, isCrash, isUnload)) {
                            inventory = snowmobile?.GetItemContainer()?.inventory;
                        }
                    }
                    break;
                    default : return;
                }
                var fuelContainer = fuelSystem?.GetFuelContainer()?.inventory;
                if (fuelContainer != null) {
                    collect.AddRange(fuelContainer.itemList);
                }
                if (inventory != null) {
                    collect.AddRange(inventory.itemList);
                }
            }
            else {
                var modularCar = entity as ModularCar;
                if (modularCar == null) return;
                bool refundFuel, refundInventory, refundEngine, refundModule;
                ModularCarRefundState(baseVehicleS, isCrash, isUnload, out refundFuel, out refundInventory, out refundEngine, out refundModule);
                foreach (var moduleEntity in modularCar.AttachedModuleEntities) {
                    if (refundEngine) {
                        var moduleEngine = moduleEntity as VehicleModuleEngine;
                        if (moduleEngine != null) {
                            var engineContainer = moduleEngine.GetContainer()?.inventory;
                            if (engineContainer != null) collect.AddRange(engineContainer.itemList);
                            continue;
                        }
                    }
                    if (refundInventory) {
                        var moduleStorage = moduleEntity as VehicleModuleStorage;
                        if (moduleStorage != null && !(moduleEntity is VehicleModuleEngine)) {
                            var storageContainer = moduleStorage.GetContainer()?.inventory;
                            if (storageContainer != null) collect.AddRange(storageContainer.itemList);
                        }
                    }
                }
                if (refundFuel) {
                    var fuelContainer = modularCar.GetFuelSystem()?.GetFuelContainer()?.inventory;
                    if (fuelContainer != null) collect.AddRange(fuelContainer.itemList);
                }
                if (refundModule) {
                    var moduleContainer = modularCar.Inventory?.ModuleContainer;
                    if (moduleContainer != null) collect.AddRange(moduleContainer.itemList);
                }
                //var chassisContainer = modularCar.Inventory?.ChassisContainer;
                //if (chassisContainer != null)
                //{
                //    collect.AddRange(chassisContainer.itemList);
                //}
            }
            if (collect.Count > 0) {
                var player = RustCore.FindPlayerById(vehicle.playerID);
                if (player == null) {
                    DropItemContainer(entity, vehicle.playerID, collect);
                }
                else {
                    for (var i = collect.Count - 1; i >= 0; i--) {
                        var item = collect[i];
                        player.GiveItem(item);
                    }
                    if (player.IsConnected) {
                        Print(player, Lang("RefundedVehicleItems", player.UserIDString, baseVehicleS.displayName));
                    }
                }
            }
            Pool.FreeList(ref collect);
        }
        private static void DropItemContainer(BaseEntity entity, ulong playerID, List<Item> collect) {
            var droppedItemContainer = GameManager.server.CreateEntity(PREFAB_ITEM_DROP, entity.GetDropPosition(), entity.transform.rotation) as DroppedItemContainer;
            droppedItemContainer.inventory = new ItemContainer();
            droppedItemContainer.inventory.ServerInitialize(null, Mathf.Min(collect.Count, droppedItemContainer.maxItemCount));
            droppedItemContainer.inventory.GiveUID();
            droppedItemContainer.inventory.entityOwner = droppedItemContainer;
            droppedItemContainer.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
            for (var i = collect.Count - 1; i >= 0; i--) {
                var item = collect[i];
                if (!item.MoveToContainer(droppedItemContainer.inventory)) {
                    item.DropAndTossUpwards(droppedItemContainer.transform.position);
                }
            }
            droppedItemContainer.OwnerID = playerID;
            droppedItemContainer.Spawn();
        }
#endregion Refund
#region GiveFuel
        private static void TryGiveFuel(BaseEntity entity, string vehicleType, IFuelVehicle iFuelVehicle) {
            if (iFuelVehicle == null || iFuelVehicle.spawnFuelAmount <= 0) return;
            ItemContainer fuelContainer;
            NormalVehicleType normalVehicleType;
            if (Enum.TryParse(vehicleType, out normalVehicleType)) {
                EntityFuelSystem fuelSystem = null;
                switch (normalVehicleType) {
                    case NormalVehicleType.Sedan : case NormalVehicleType.Chinook : case NormalVehicleType.RidableHorse : return;
                    case NormalVehicleType.MiniCopter : case NormalVehicleType.TransportHelicopter : fuelSystem = (entity as MiniCopter)?.GetFuelSystem();
                    break;
                    case NormalVehicleType.HotAirBalloon : fuelSystem = (entity as HotAirBalloon)?.fuelSystem;
                    break;
                    case NormalVehicleType.RHIB : case NormalVehicleType.Rowboat : fuelSystem = (entity as MotorRowboat)?.GetFuelSystem();
                    break;
                    case NormalVehicleType.WorkCart : fuelSystem = (entity as TrainEngine)?.GetFuelSystem();
                    break;
                    case NormalVehicleType.MagnetCrane : fuelSystem = (entity as BaseCrane)?.GetFuelSystem();
                    break;
                    case NormalVehicleType.SubmarineSolo : case NormalVehicleType.SubmarineDuo : fuelSystem = (entity as BaseSubmarine)?.GetFuelSystem();
                    break;
                    case NormalVehicleType.Snowmobile : case NormalVehicleType.TomahaSnowmobile : fuelSystem = (entity as Snowmobile)?.GetFuelSystem();
                    break;
                    default : return;
                }
                fuelContainer = fuelSystem?.GetFuelContainer()?.inventory;
            }
            else {
                fuelContainer = (entity as ModularCar)?.GetFuelSystem()?.GetFuelContainer()?.inventory;
            }
            if (fuelContainer == null  /*|| fuelContainer.FindItemByItemID(ITEMID_FUEL) != null*/
            ) return;
            var fuel = ItemManager.CreateByItemID(ITEMID_FUEL, iFuelVehicle.spawnFuelAmount);
            if (!fuel.MoveToContainer(fuelContainer)) {
                fuel.Remove();
            }
        }
#endregion GiveFuel
#region VehicleModules
        private void AttacheVehicleModules(ModularCar modularCar, ModularVehicleS modularVehicleS, string vehicleType) {
            foreach (var moduleItem in modularVehicleS.CreateModuleItems()) {
                if (!modularCar.TryAddModule(moduleItem)) {
                    PrintError($"Module item '{moduleItem.info.shortname}' in '{vehicleType}' cannot be attached to the vehicle");
                    moduleItem.Remove();
                }
            }
        }
        private void AddItemsToVehicleEngine(ModularCar modularCar, ModularVehicleS modularVehicleS, string vehicleType) {
            if (modularCar == null || modularCar.IsDestroyed) return;
            foreach (var moduleEntity in modularCar.AttachedModuleEntities) {
                var vehicleModuleEngine = moduleEntity as VehicleModuleEngine;
                if (vehicleModuleEngine != null) {
                    var engineInventory = vehicleModuleEngine.GetContainer()?.inventory;
                    if (engineInventory != null) {
                        foreach (var engineItem in modularVehicleS.CreateEngineItems()) {
                            bool moved = false;
                            for (int i = 0; i < engineInventory.capacity; i++) {
                                if (engineItem.MoveToContainer(engineInventory, i, false)) {
                                    moved = true;
                                    break;
                                }
                            }
                            if (!moved) {
                                PrintError($"Engine item '{engineItem.info.shortname}' in '{vehicleType}' cannot be move to the vehicle engine inventory");
                                engineItem.Remove();
                                engineItem.DoRemove();
                            }
                        }
                    }
                }
            }
        }
#endregion VehicleModules
#region DropInventory
        private static bool CanDropInventory(BaseVehicleS baseVehicleS) {
            var inventoryVehicle = baseVehicleS as IInventoryVehicle;
            return inventoryVehicle != null && inventoryVehicle.dropInventoryOnRecall;
        }
        private void DropVehicleInventoryItems(BasePlayer player, string vehicleType, BaseEntity entity, BaseVehicleS baseVehicleS) {
            DroppedItemContainer droppedItemContainer = null;
            NormalVehicleType normalVehicleType;
            if (Enum.TryParse(vehicleType, out normalVehicleType)) {
                ItemContainer itemContainer = null;
                switch (normalVehicleType) {
                    case NormalVehicleType.Sedan : case NormalVehicleType.MiniCopter : case NormalVehicleType.TransportHelicopter : case NormalVehicleType.Chinook : case NormalVehicleType.WorkCart : case NormalVehicleType.MagnetCrane : return;
                    case NormalVehicleType.RHIB : case NormalVehicleType.Rowboat : itemContainer = ((entity as MotorRowboat)?.storageUnitInstance.Get(true) as StorageContainer)?.inventory;
                    break;
                    case NormalVehicleType.HotAirBalloon : itemContainer = ((entity as HotAirBalloon)?.storageUnitInstance.Get(true) as StorageContainer)?.inventory;
                    break;
                    case NormalVehicleType.RidableHorse : itemContainer = (entity as RidableHorse)?.inventory;
                    break;
                    case NormalVehicleType.SubmarineSolo : case NormalVehicleType.SubmarineDuo : itemContainer = (entity as BaseSubmarine)?.GetTorpedoContainer()?.inventory;
                    break;
                    case NormalVehicleType.Snowmobile : case NormalVehicleType.TomahaSnowmobile : itemContainer = (entity as Snowmobile)?.GetItemContainer()?.inventory;
                    break;
                }
                if (itemContainer != null) {
                    droppedItemContainer = itemContainer.Drop(PREFAB_ITEM_DROP, entity.GetDropPosition(), entity.transform.rotation);
                }
            }
            else {
                var modularCar = entity as ModularCar;
                if (modularCar == null) return;
                foreach (var moduleEntity in modularCar.AttachedModuleEntities) {
                    if (moduleEntity is VehicleModuleEngine) continue;
                    var moduleStorage = moduleEntity as VehicleModuleStorage;
                    if (moduleStorage != null) {
                        droppedItemContainer = moduleStorage.GetContainer()?.inventory?.Drop(PREFAB_ITEM_DROP, entity.GetDropPosition(), entity.transform.rotation);
                    }
                }
            }
            if (droppedItemContainer != null) {
                Print(player, Lang("VehicleInventoryDropped", player.UserIDString, baseVehicleS.displayName));
            }
        }
#endregion DropInventory
#region TryPay
        private bool TryPay(BasePlayer player, Dictionary<string, PriceInfo> prices, out string missingResources) {
            if (permission.UserHasPermission(player.UserIDString, PERMISSION_BYPASS_COST)) {
                missingResources = null;
                return true;
            }
            if (!CanPay(player, prices, out missingResources)) {
                return false;
            }
            var collect = Pool.GetList<Item>();
            foreach (var entry in prices) {
                if (entry.Value.amount <= 0) continue;
                var itemDefinition = ItemManager.FindItemDefinition(entry.Key);
                if (itemDefinition != null) {
                    player.inventory.Take(collect, itemDefinition.itemid, entry.Value.amount);
                    player.Command("note.inv", itemDefinition.itemid, -entry.Value.amount);
                    continue;
                }
                switch (entry.Key.ToLower()) {
                    case "economics" : Economics?.Call("Withdraw", player.userID, (double)entry.Value.amount);
                    continue;
                    case "serverrewards" : ServerRewards?.Call("TakePoints", player.userID, entry.Value.amount);
                    continue;
                }
            }
            foreach (var item in collect) {
                item.Remove();
            }
            Pool.FreeList(ref collect);
            missingResources = null;
            return true;
        }
        private readonly Hash<string, int> missingDictionary = new Hash<string, int>();
        private bool CanPay(BasePlayer player, Dictionary<string, PriceInfo> prices, out string missingResources) {
            missingDictionary.Clear();
            var language = RustTranslationAPI != null ? lang.GetLanguage(player.UserIDString) : null;
            foreach (var entry in prices) {
                if (entry.Value.amount <= 0) continue;
                int missingAmount;
                var itemDefinition = ItemManager.FindItemDefinition(entry.Key);
                if (itemDefinition != null) missingAmount = entry.Value.amount - player.inventory.GetAmount(itemDefinition.itemid);
                else missingAmount = CheckBalance(entry.Key, entry.Value.amount, player.userID);
                if (missingAmount <= 0) continue;
                var displayName = GetItemDisplayName(language, entry.Key, entry.Value.displayName);
                missingDictionary[displayName] += missingAmount;
            }
            if (missingDictionary.Count > 0) {
                StringBuilder stringBuilder = Pool.Get<StringBuilder>();
                foreach (var entry in missingDictionary) {
                    stringBuilder.AppendLine($"* {Lang("PriceFormat", player.UserIDString, entry.Key, entry.Value)}");
                }
                missingResources = stringBuilder.ToString();
                stringBuilder.Clear();
                Pool.Free(ref stringBuilder);
                return false;
            }
            missingResources = null;
            return true;
        }
        private int CheckBalance(string key, int price, ulong playerID) {
            switch (key.ToLower()) {
                case "economics" : var balance = Economics?.Call("Balance", playerID);
                if (balance is double) {
                    var n = price - (double)balance;
                    return n <= 0 ? 0 : (int)Math.Ceiling(n);
                }
                return price;
                case "serverrewards" : var points = ServerRewards?.Call("CheckPoints", playerID);
                if (points is int) {
                    var n = price - (int)points;
                    return n <= 0 ? 0 : n;
                }
                return price;
                default : PrintError($"Unknown Currency Type '{key}'");
                return price;
            }
        }
#endregion TryPay
#region AreFriends
        private bool AreFriends(ulong playerID, ulong friendID) {
            if (playerID == friendID) return true;
            if (configData.globalS.useTeams && SameTeam(playerID, friendID)) return true;
            if (configData.globalS.useFriends && HasFriend(playerID, friendID)) return true;
            if (configData.globalS.useClans && SameClan(playerID, friendID)) return true;
            return false;
        }
        private static bool SameTeam(ulong playerID, ulong friendID) {
            if (!RelationshipManager.TeamsEnabled()) return false;
            var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerID);
            if (playerTeam == null) return false;
            var friendTeam = RelationshipManager.ServerInstance.FindPlayersTeam(friendID);
            if (friendTeam == null) return false;
            return playerTeam == friendTeam;
        }
        private bool HasFriend(ulong playerID, ulong friendID) {
            if (Friends == null) return false;
            return (bool)Friends.Call("HasFriend", playerID, friendID);
        }
        private bool SameClan(ulong playerID, ulong friendID) {
            if (Clans == null) return false;
            //Clans
            var isMember = Clans.Call("IsClanMember", playerID.ToString(), friendID.ToString());
            if (isMember != null) return (bool)isMember;
            //Rust:IO Clans
            var playerClan = Clans.Call("GetClanOf", playerID);
            if (playerClan == null) return false;
            var friendClan = Clans.Call("GetClanOf", friendID);
            if (friendClan == null) return false;
            return (string)playerClan == (string)friendClan;
        }
#endregion AreFriends
#region IsPlayerBlocked
        private bool IsPlayerBlocked(BasePlayer player) {
            if (NoEscape == null) return false;
            if (configData.globalS.useRaidBlocker && IsRaidBlocked(player.UserIDString)) {
                Print(player, Lang("RaidBlocked", player.UserIDString));
                return true;
            }
            if (configData.globalS.useCombatBlocker && IsCombatBlocked(player.UserIDString)) {
                Print(player, Lang("CombatBlocked", player.UserIDString));
                return true;
            }
            return false;
        }
        private bool IsRaidBlocked(string playerID) => (bool)NoEscape.Call("IsRaidBlocked", playerID);
        private bool IsCombatBlocked(string playerID) => (bool)NoEscape.Call("IsCombatBlocked", playerID);
#endregion IsPlayerBlocked
#region GetBaseVehicleS
        private BaseVehicleS GetBaseVehicleS(string vehicleName) {
            BaseVehicleS baseVehicleS;
            return allBaseVehicleSettings.TryGetValue(vehicleName, out baseVehicleS) ? baseVehicleS : null;
        }
        private BaseVehicleS GetBaseVehicleS(NormalVehicleType normalVehicleType) {
            switch (normalVehicleType) {
                case NormalVehicleType.Rowboat : return configData.normalVehicleS.rowboatS;
                case NormalVehicleType.RHIB : return configData.normalVehicleS.rhibS;
                case NormalVehicleType.Sedan : return configData.normalVehicleS.sedanS;
                case NormalVehicleType.HotAirBalloon : return configData.normalVehicleS.hotAirBalloonS;
                case NormalVehicleType.MiniCopter : return configData.normalVehicleS.miniCopterS;
                case NormalVehicleType.TransportHelicopter : return configData.normalVehicleS.transportHelicopterS;
                case NormalVehicleType.Chinook : return configData.normalVehicleS.chinookS;
                case NormalVehicleType.RidableHorse : return configData.normalVehicleS.ridableHorseS;
                case NormalVehicleType.WorkCart : return configData.normalVehicleS.workCartS;
                case NormalVehicleType.MagnetCrane : return configData.normalVehicleS.magnetCraneS;
                case NormalVehicleType.SubmarineSolo : return configData.normalVehicleS.submarineSoloS;
                case NormalVehicleType.SubmarineDuo : return configData.normalVehicleS.submarineDuoS;
                case NormalVehicleType.Snowmobile : return configData.normalVehicleS.snowmobileS;
                case NormalVehicleType.TomahaSnowmobile : return configData.normalVehicleS.tomahaSnowmobileS;
                default : return null;
            }
        }
#endregion GetBaseVehicleS
#region HasVehiclePermission
        private bool CanViewVehicleInfo(BasePlayer player, string vehicleType, BaseVehicleS baseVehicleS) {
            if (baseVehicleS.purchasable && baseVehicleS.commands.Count > 0) {
                return HasVehiclePermission(player, vehicleType, baseVehicleS);
            }
            return false;
        }
        private bool HasVehiclePermission(BasePlayer player, string vehicleType, BaseVehicleS baseVehicleS = null) {
            if (baseVehicleS == null) baseVehicleS = GetBaseVehicleS(vehicleType);
            if (!baseVehicleS.usePermission || string.IsNullOrEmpty(baseVehicleS.permission)) return true;
            return permission.UserHasPermission(player.UserIDString, PERMISSION_ALL) || permission.UserHasPermission(player.UserIDString, baseVehicleS.permission);
        }
#endregion HasVehiclePermission
#region GetCooldown
        private double GetSpawnCooldown(BasePlayer player, BaseVehicleS baseVehicleS) {
            double cooldown = baseVehicleS.spawnCooldown;
            foreach (var entry in baseVehicleS.cooldownPermissions) {
                if (cooldown > entry.Value.spawnCooldown && permission.UserHasPermission(player.UserIDString, entry.Key)) {
                    cooldown = entry.Value.spawnCooldown;
                }
            }
            return cooldown;
        }
        private double GetRecallCooldown(BasePlayer player, BaseVehicleS baseVehicleS) {
            double cooldown = baseVehicleS.recallCooldown;
            foreach (var entry in baseVehicleS.cooldownPermissions) {
                if (cooldown > entry.Value.recallCooldown && permission.UserHasPermission(player.UserIDString, entry.Key)) {
                    cooldown = entry.Value.recallCooldown;
                }
            }
            return cooldown;
        }
#endregion GetCooldown
#region ClaimVehicle
        private bool TryClaimVehicle(BasePlayer player, BaseEntity entity, NormalVehicleType normalVehicleType) {
            return TryClaimVehicle(player, entity, normalVehicleType.ToString());
        }
        private bool TryClaimVehicle(BasePlayer player, BaseEntity entity, string vehicleType) {
            Vehicle vehicle;
            if (!st
// ... [Code preview truncated due to length. Full source in attached file] ...

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