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

FREE Sputnik : 1.0.8 1.0.8

Нет прав для скачивания
C#:
using System.Collections.Generic;
using Newtonsoft.Json;
using CompanionServer.Handlers;
using Oxide.Plugins.SputnikExtensionMethods;
using UnityEngine;
using System;
using Oxide.Core.Plugins;
using Network;
using Rust;
using System.Collections;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using System.Reflection;
namespace Oxide.Plugins {
    [Info("Sputnik", "Sempai#3239", "1.0.8")]
    class Sputnik : RustPlugin {
#region Variables
        [PluginReference]
        Plugin NpcSpawn, PveMode, GUIAnnouncements, DiscordMessages, ZoneManager, RaidableBases;
        const bool en = false;
        static Sputnik ins;
        EventClass eventClass;
        static Dictionary<string, List<EntData>> saveData;
        Coroutine findSpawnPointsCorountine;
        Coroutine autoEventCorountine;
        HashSet<string> subscribeMethods = new HashSet<string> {
            "OnCardSwipe", "CanHackCrate", "OnLootEntity", "CanLootEntity", "OnEntityDeath", "OnEntityKill", "OnCorpsePopulate", "CanPopulateLoot", "OnCustomLootContainer", "CanEntityTakeDamage", "OnTrapTrigger", "OnTurretTarget", "CanEntityBeTargeted", "OnEntityTakeDamage", "OnPlayerSleep"
        }
        ;
#endregion Variables
#region Hooks
        void Init() => Unsubscribes();
        void OnServerInitialized() {
            PrintWarning("\n-----------------------------\n" + " Author - Sempai#3239\n" + " VK - https://vk.com/rustnastroika/n" + " Forum - https://darkplugins.ru/n" + " Discord - https://discord.gg/5DPTsRmd3G/n" + "-----------------------------");
            ins = this;
            PostLoadCheck();
            UpdateConfig();
            LoadDefaultMessages();
            LoadData();
            FindNewEventPoints();
            if (_config.mainConfig.isAutoEvent) autoEventCorountine = ServerMgr.Instance.StartCoroutine(AutoEventCorountine());
        }
        void Unload() {
            StopEvent();
            if (findSpawnPointsCorountine != null) ServerMgr.Instance.StopCoroutine(findSpawnPointsCorountine);
            if (autoEventCorountine != null) ServerMgr.Instance.StopCoroutine(autoEventCorountine);
        }
        object OnCardSwipe(CardReader cardReader, Keycard keycard, BasePlayer player) {
            if (eventClass == null || player == null || cardReader == null || keycard == null) return null;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromCardReaderUid(cardReader.net.ID);
            Item keyCardItem = keycard.GetItem();
            if (keyCardItem == null) return null;
            if (keyCardItem.info.shortname == ins._config.customCardConfig.shortName && keyCardItem.skin == ins._config.customCardConfig.skinID) {
                if (sputnikClass != null && !sputnikClass.cardReaderOpen) {
                    keyCardItem.LoseCondition(_config.customCardConfig.helthLossScale);
                    sputnikClass.cardReaderOpen = true;
                    return true;
                }
                else if (keyCardItem.skin != 0) return true;
            }
            else if (sputnikClass != null) InformPlayer(player, "NeedUseCard", _config.prefix);
            return null;
        }
        object CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
            if (eventClass == null || player == null || crate == null) return null;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromCrateUid(crate.net.ID);
            if (sputnikClass != null) {
                if (!sputnikClass.CanOpenCrate(crate.net.ID)) {
                    InformPlayer(player, "NeedUseCard", _config.prefix);
                    return true;
                }
                else ActionEconomy(player.userID, "LockedCrate");
            }
            return null;
        }
        void OnLootEntity(BasePlayer player, LootContainer container) {
            if (eventClass == null || player == null || container == null) return;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromCrateUid(container.net.ID);
            if (sputnikClass != null) {
                sputnikClass.OnCratelooted(container.net.ID);
                ActionEconomy(player.userID, "Crates", container.PrefabName);
            }
        }
        object CanLootEntity(BasePlayer player, LootContainer container) {
            if (eventClass == null || player == null || container == null) return null;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromCrateUid(container.net.ID);
            if (sputnikClass != null) {
                if (!sputnikClass.CanOpenCrate(container.net.ID)) {
                    InformPlayer(player, "NeedUseCard", _config.prefix);
                    return true;
                }
            }
            return null;
        }
        void OnLootSpawn(LootContainer container) {
            if (!_config.customCardConfig.enableSpawnInDefaultCrates || container == null || container.inventory == null) return;
            float chance = 0;
            if (!_config.customCardConfig.spawnSetting.TryGetValue(container.PrefabName, out chance) || chance == 0) return;
            if (UnityEngine.Random.Range(0f, 100f) <= chance) {
                Item item = CreateCustomCardItem();
                container.inventory.Remove(container.inventory.itemList.FirstOrDefault(x => true));
                if (!item.MoveToContainer(container.inventory)) item.Remove();
            }
        }
        object OnEntityTakeDamage(ScientistNPC scientistNPC, HitInfo info) {
            if (eventClass == null || scientistNPC == null || info == null || info.Initiator == null) return null;
            NpcConfig npcConfig = _config.npcConfigs.FirstOrDefault(x => x.name == scientistNPC.displayName);
            if (npcConfig == null) return null;
            AutoTurret autoTurret = info.Initiator as AutoTurret;
            if (autoTurret == null) return null;
            if (eventClass.IsEventTurret(autoTurret.net.ID)) return true;
            return null;
        }
        object OnEntityTakeDamage(AutoTurret autoTurret, HitInfo info) {
            if (eventClass == null || autoTurret == null) return null;
            if (eventClass.IsEventTurret(autoTurret.net.ID) && (info.InitiatorPlayer == null || !info.InitiatorPlayer.IsRealPlayer())) return true;
            return null;
        }
        void OnEntityDeath(ScientistNPC scientistNPC, HitInfo info) {
            if (eventClass == null || scientistNPC == null || info == null) return;
            if (info.InitiatorPlayer.IsRealPlayer() && _config.npcConfigs.Any(x => x != null && x.name == scientistNPC.displayName)) ActionEconomy(info.InitiatorPlayer.userID, "Npc");
        }
        void OnEntityDeath(BasePlayer player, HitInfo info) {
            OnPlayerSleep(player);
        }
        void OnPlayerSleep(BasePlayer player) {
            if (eventClass == null || !player.IsRealPlayer()) return;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromPLayerInZoneUid(player.userID);
            if (sputnikClass != null) {
                sputnikClass.RemovePlayerFromZone(player);
            }
        }
        void OnCorpsePopulate(BasePlayer entity, NPCPlayerCorpse corpse) {
            if (eventClass != null || entity == null || corpse == null) return;
            if (entity is ScientistNPC) {
                NpcConfig npcConfig = _config.npcConfigs.FirstOrDefault(x => x.name == entity.displayName);
                if (npcConfig == null) return;
                NextTick(() => {
                    if (corpse == null) return;
                    ItemContainer container = corpse.containers[0];
                    if (npcConfig.typeLootTable == 0) {
                        for (int i = container.itemList.Count - 1; i >= 0; i--) {
                            Item item = container.itemList[i];
                            if (npcConfig.wearItems.Any(x => x.shortName == item.info.shortname)) {
                                item.RemoveFromContainer();
                                item.Remove();
                            }
                        }
                        if (npcConfig.deleteCorpse && corpse != null && !corpse.IsDestroyed) corpse.Kill();
                        return;
                    }
                    if (npcConfig.typeLootTable == 2 || npcConfig.typeLootTable == 3) {
                        if (npcConfig.deleteCorpse && !corpse.IsDestroyed) corpse.Kill();
                        return;
                    }
                    container.ClearItemsContainer();
                    if (npcConfig.typeLootTable == 1 && npcConfig.lootTable.minAmount > 0) AddToContainerItem(container, npcConfig.lootTable, npcConfig.typeLootTable);
                    if (npcConfig.deleteCorpse && corpse != null && !corpse.IsDestroyed) corpse.Kill();
                }
                );
            }
        }
        object OnTrapTrigger(BaseTrap baseTrap, GameObject gameObject) {
            if (baseTrap == null) return null;
            ScientistNPC scientistNPC = gameObject.ToBaseEntity() as ScientistNPC;
            if (scientistNPC != null && _config.npcConfigs.Any(x => x.name == scientistNPC.displayName)) return true;
            return null;
        }
        object OnTurretTarget(AutoTurret turret, BasePlayer player) {
            if (eventClass == null || !turret.IsExists() || !player.IsExists()) return null;
            if (!eventClass.IsEventTurret(turret.net.ID)) return null;
            if (!player.IsRealPlayer()) return true;
            return null;
        }
#region OtherPlugins
        object CanPopulateLoot(ScientistNPC entity, NPCPlayerCorpse corpse) {
            if (eventClass == null || entity == null || corpse == null) return null;
            NpcConfig npcConfig = _config.npcConfigs.FirstOrDefault(x => x.name == entity.displayName);
            if (npcConfig != null && npcConfig.typeLootTable != 2) return true;
            return null;
        }
        object CanPopulateLoot(LootContainer container) {
            if (eventClass == null || container == null) return null;
            string cratePresetName = null;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromCrateUid(container.net.ID);
            if (sputnikClass == null) return null;
            if (container is HackableLockedCrate) {
                if (sputnikClass.lockedCrates.Any(y => y.Key != null && y.Key.net.ID == container.net.ID)) cratePresetName = sputnikClass.lockedCrates[container];
            }
            else if (sputnikClass.crates.Any(y => y.Key != null && y.Key.net.ID == container.net.ID)) cratePresetName = sputnikClass.crates[container];
            if (cratePresetName == null) return null;
            CrateConfig crateConfig = _config.crateConfigs.FirstOrDefault(x => x.presetName == cratePresetName);
            if (crateConfig != null && crateConfig.typeLootTable != 2) return true;
            return null;
        }
        object OnCustomLootContainer(uint netID) {
            if (eventClass == null) return null;
            SputnikClass sputnikClass = eventClass.GetSputnikClassFromCrateUid(netID);
            if (sputnikClass == null) return null;
            string cratePresetName = null;
            if (sputnikClass.lockedCrates.Any(y => y.Key != null && y.Key.net.ID == netID)) cratePresetName = sputnikClass.lockedCrates.FirstOrDefault(y => y.Key != null && y.Key.net.ID == netID).Value;
            else if (sputnikClass.crates.Any(y => y.Key != null && y.Key.net.ID == netID)) cratePresetName = sputnikClass.crates.FirstOrDefault(y => y.Key != null && y.Key.net.ID == netID).Value;
            if (cratePresetName == null) return null;
            CrateConfig crateConfig = _config.crateConfigs.FirstOrDefault(x => x.presetName == cratePresetName);
            if (crateConfig != null && crateConfig.typeLootTable != 3) return true;
            return null;
        }
        object CanEntityTakeDamage(AutoTurret autoTurret, HitInfo hitinfo) {
            if (eventClass == null || autoTurret == null || hitinfo == null) return null;
            if (eventClass.IsEventTurret(autoTurret.net.ID)) {
                if (hitinfo.InitiatorPlayer == null || !hitinfo.InitiatorPlayer.IsRealPlayer()) return false;
                else return true;
            }
            return null;
        }
        object CanEntityTakeDamage(Landmine landmine, HitInfo hitinfo) {
            if (eventClass == null || landmine == null || hitinfo == null) return null;
            if (eventClass.IsEventMine(landmine.net.ID)) {
                if (hitinfo.InitiatorPlayer == null || !hitinfo.InitiatorPlayer.IsRealPlayer()) return false;
                else return true;
            }
            return null;
        }
        object CanEntityTakeDamage(ScientistNPC scientistNPC, HitInfo hitinfo) {
            if (eventClass == null || scientistNPC == null || hitinfo == null || hitinfo.Initiator == null) return null;
            NpcConfig npcConfig = _config.npcConfigs.FirstOrDefault(x => x.name == scientistNPC.displayName);
            if (npcConfig == null) return null;
            AutoTurret autoTurret = hitinfo.Initiator as AutoTurret;
            if (autoTurret == null) return null;
            if (eventClass.IsEventTurret(autoTurret.net.ID)) return false;
            return null;
        }
        object CanEntityTakeDamage(BasePlayer victim, HitInfo hitinfo) {
            if (eventClass == null || victim == null || hitinfo == null || !victim.userID.IsSteamId()) return null;
            BasePlayer attacker = hitinfo.InitiatorPlayer;
            if (attacker != null) {
                SputnikClass sputnikClass = eventClass.GetSputnikClassFromPLayerInZoneUid(victim.userID);
                if (sputnikClass != null && sputnikClass.sputnikDebrisConfig.zoneConfig.isCreateZonePVP && (attacker == null || (attacker != null && eventClass.GetSputnikClassFromPLayerInZoneUid(attacker.userID) != null))) return true;
            }
            else if (hitinfo.Initiator != null) {
                AutoTurret autoTurret = hitinfo.Initiator as AutoTurret;
                if (autoTurret != null) {
                    if (eventClass.IsEventTurret(autoTurret.net.ID)) return true;
                    return null;
                }
                BaseTrap baseTrap = hitinfo.Initiator as BaseTrap;
                if (baseTrap != null) {
                    if (eventClass.IsEventMine(baseTrap.net.ID)) return true;
                    return null;
                }
            }
            return null;
        }
        object CanEntityTrapTrigger(BaseTrap trap, BasePlayer player) {
            if (eventClass == null || trap == null) return null;
            if (eventClass.IsEventMine(trap.net.ID)) return true;
            return null;
        }
        object CanEntityBeTargeted(BasePlayer player, BaseEntity turret) {
            if (eventClass == null || turret == null || !player.IsRealPlayer()) return null;
            if (eventClass.IsEventTurret(turret.net.ID)) return true;
            return null;
        }
#endregion OtherPlugins
#endregion Hooks
#region Commands
        [ChatCommand("sputnikstart")]
        void ChatStartCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            if (arg != null && arg.Length >= 1) StartEvent(arg[0], player);
            else StartEvent(activator : player);
        }
        [ChatCommand("sputnikstop")]
        void ChatStopCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            StopEvent();
        }
        [ConsoleCommand("sputnikstart")]
        void ConsoleStartCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            if (arg.Args != null && arg.Args.Length > 0) StartEvent(arg.Args[0]);
            StartEvent();
            Puts("Event activated");
        }
        [ConsoleCommand("sputnikstop")]
        void ConsoleStopCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() == null) StopEvent();
        }
        [ChatCommand("givespacecard")]
        void GiveCustomItemChatCommand(BasePlayer player, string command, string[] arg) {
            if (player == null || !player.IsAdmin || arg == null) return;
            MoveItem(player, CreateCustomCardItem());
            PrintToChat(player, GetMessage("GetSpaceCard", player.UserIDString, _config.prefix));
        }
        [ConsoleCommand("givespacecard")]
        void GiveCustomItemCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            BasePlayer target = null;
            if (arg.Args.Length >= 1) target = BasePlayer.FindByID(Convert.ToUInt64(arg.Args[0]));
            if (target == null) {
                PrintToConsole(player, "Player not found");
                return;
            }
            MoveItem(target, CreateCustomCardItem());
            PrintToChat(target, GetMessage("GetSpaceCard", target.UserIDString, _config.prefix));
            Puts($"A space card was given to {target.displayName}");
        }
#endregion Commands
#region Methods
        void PostLoadCheck() {
            if (!plugins.Exists("NpcSpawn")) {
                PrintError("NpcSpawn plugin doesn`t exist! Please read the file ReadMe.txt");
                NextTick(() => Server.Command($"o.unload {Name}"));
                return;
            }
        }
        void UpdateConfig() {
            if (_config.version == Version) return;
            if (_config.version.Minor == 0) {
                if (_config.version.Patch <= 2) {
                    _config.supportedPluginsConfig.zoneManager = new ZoneManagerConfig {
                        enable = false, blockFlags = new HashSet<string> {
                            "eject", "pvegod"
                        }
                    }
                    ;
                }
                if (_config.version.Patch <= 3) {
                    _config.supportedPluginsConfig.raidableBases = new RaidableBasesConfig();
                    _config.spawnConfig.minTCDistance = 25;
                    _config.mainConfig.destroyAfterLootingTime = 300;
                }
            }
            _config.version = Version;
            SaveConfig();
        }
        void LoadData() {
            saveData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, List<EntData>>>(ins.Title);
            if (saveData == null || saveData.Count == 0) {
                PrintError("Data file not found");
                NextTick(() => Server.Command($"o.unload {Name}"));
            }
        }
        void Unsubscribes() {
            foreach (string hook in subscribeMethods) Unsubscribe(hook);
            if (!_config.customCardConfig.enableSpawnInDefaultCrates) Unsubscribe("OnLootSpawn");
        }
        void Subscribes() {
            foreach (string hook in subscribeMethods) Subscribe(hook);
        }
        void StartEvent(string presetName = "", BasePlayer activator = null) {
            if (eventClass != null) {
                SendErrorMessage(GetMessage("EventActive", activator != null ? activator.UserIDString : null, _config.prefix), activator);
                return;
            }
            StopEvent();
            EventConfig eventConfig = DefineEventConfig(presetName);
            if (eventConfig == null) {
                SendErrorMessage("Event preset not found!", activator);
                return;
            }
            if (autoEventCorountine != null) ServerMgr.Instance.StopCoroutine(autoEventCorountine);
            LocationDefiner.CacheBuildingPrivilegeLocations();
            eventClass = new EventClass();
            eventClass.StartEvent(eventConfig);
            Interface.CallHook("OnSputnikEventStart");
        }
        void StopEvent() {
            if (eventClass != null) {
                if (autoEventCorountine != null) ServerMgr.Instance.StopCoroutine(autoEventCorountine);
                if (_config.mainConfig.isAutoEvent) autoEventCorountine = ServerMgr.Instance.StartCoroutine(AutoEventCorountine());
                eventClass.StopEvent();
                eventClass = null;
                FindNewEventPoints();
                InformAllPlayers("EndEvent", _config.prefix);
                Interface.CallHook("OnSputnikEventStop");
                DefineEventWinner();
                SendBalance();
                Unsubscribes();
            }
        }
        EventConfig DefineEventConfig(string presetName) {
            if (presetName != "") {
                return ins._config.eventConfigs.FirstOrDefault(x => x.presetName.Contains(presetName));
            }
            else if (ins._config.eventConfigs.Any(x => x.chance > 0)) {
                while (true) {
                    foreach (EventConfig checkEventConfig in ins._config.eventConfigs) {
                        float chance = UnityEngine.Random.Range(0, 100);
                        if (chance <= checkEventConfig.chance) {
                            return checkEventConfig;
                        }
                    }
                }
            }
            return null;
        }
        void FindNewEventPoints() {
            if (findSpawnPointsCorountine != null) ServerMgr.Instance.StopCoroutine(findSpawnPointsCorountine);
            findSpawnPointsCorountine = ServerMgr.Instance.StartCoroutine(LocationDefiner.FindSpawnPosition());
        }
        IEnumerator AutoEventCorountine() {
            yield return CoroutineEx.waitForSeconds(UnityEngine.Random.Range(_config.mainConfig.minTimeBetweenEvent, _config.mainConfig.maxTimeBetweenEvent));
            StartEvent();
        }
        void AddToContainerItem(ItemContainer container, LootTableConfig lootTableConfig, int typeOfLootTable) {
            if (typeOfLootTable == 1) container.ClearItemsContainer();
            int CountLootInContainer = 0;
            int countLoot = UnityEngine.Random.Range(lootTableConfig.minAmount, lootTableConfig.maxAmount);
            if (typeOfLootTable == 4) container.capacity += countLoot;
            else container.capacity = countLoot;
            for (; CountLootInContainer < countLoot;) {
                foreach (ItemConfig item in lootTableConfig.itemsConfig) {
                    if (UnityEngine.Random.Range(0.0f, 100.0f) <= item.chance) {
                        int amount = UnityEngine.Random.Range(item.minAmount, item.maxAmount);
                        Item newItem = item.isBluePrint ? ItemManager.CreateByName("blueprintbase") : ItemManager.CreateByName(item.shortName, amount, item.skinID);
                        if (item.isBluePrint) newItem.blueprintTarget = ItemManager.FindItemDefinition(item.shortName).itemid;
                        if (item.name != "") newItem.name = item.name;
                        if (!newItem.MoveToContainer(container)) newItem.Remove();
                        if (CountLootInContainer == countLoot) return;
                        CountLootInContainer++;
                    }
                }
            }
        }
#region MoveItem
        void MoveItem(BasePlayer player, Item item) {
            int spaceCountItem = GetSpaceCountItem(player, item.info.shortname, item.MaxStackable(), item.skin);
            int inventoryItemCount;
            if (spaceCountItem > item.amount) inventoryItemCount = item.amount;
            else inventoryItemCount = spaceCountItem;
            if (inventoryItemCount > 0) {
                Item itemInventory = ItemManager.CreateByName(item.info.shortname, inventoryItemCount, item.skin);
                if (item.skin != 0) itemInventory.name = item.name;
                item.amount -= inventoryItemCount;
                MoveInventoryItem(player, itemInventory);
            }
            if (item.amount > 0) MoveOutItem(player, item);
        }
        int GetSpaceCountItem(BasePlayer player, string shortname, int stack, ulong skinID) {
            int slots = player.inventory.containerMain.capacity + player.inventory.containerBelt.capacity;
            int taken = player.inventory.containerMain.itemList.Count + player.inventory.containerBelt.itemList.Count;
            int result = (slots - taken) * stack;
            foreach (Item item in player.inventory.AllItems()) if (item.info.shortname == shortname && item.skin == skinID && item.amount < stack) result += stack - item.amount;
            return result;
        }
        void MoveInventoryItem(BasePlayer player, Item item) {
            if (item.amount <= item.MaxStackable()) {
                foreach (Item itemInv in player.inventory.AllItems()) {
                    if (itemInv.info.shortname == item.info.shortname && itemInv.skin == item.skin && itemInv.amount < itemInv.MaxStackable()) {
                        if (itemInv.amount + item.amount <= itemInv.MaxStackable()) {
                            itemInv.amount += item.amount;
                            itemInv.MarkDirty();
                            return;
                        }
                        else {
                            item.amount -= itemInv.MaxStackable() - itemInv.amount;
                            itemInv.amount = itemInv.MaxStackable();
                        }
                    }
                }
                if (item.amount > 0) player.inventory.GiveItem(item);
            }
            else {
                while (item.amount > item.MaxStackable()) {
                    Item thisItem = ItemManager.CreateByName(item.info.shortname, item.MaxStackable(), item.skin);
                    if (item.skin != 0) thisItem.name = item.name;
                    player.inventory.GiveItem(thisItem);
                    item.amount -= item.MaxStackable();
                }
                if (item.amount > 0) player.inventory.GiveItem(item);
            }
        }
        void MoveOutItem(BasePlayer player, Item item) {
            if (item.amount <= item.MaxStackable()) item.Drop(player.transform.position, Vector3.up);
            else {
                while (item.amount > item.MaxStackable()) {
                    Item thisItem = ItemManager.CreateByName(item.info.shortname, item.MaxStackable(), item.skin);
                    if (item.skin != 0) thisItem.name = item.name;
                    thisItem.Drop(player.transform.position, Vector3.up);
                    item.amount -= item.MaxStackable();
                }
                if (item.amount > 0) item.Drop(player.transform.position, Vector3.up);
            }
        }
        Item CreateCustomCardItem() {
            Item item = ItemManager.CreateByName(_config.customCardConfig.shortName, 1, _config.customCardConfig.skinID);
            if (_config.customCardConfig.name != "") item.name = _config.customCardConfig.name;
            return item;
        }
#endregion MoveItem
#region Notify
        void SendErrorMessage(string message, BasePlayer player = null) {
            if (player != null) PrintToChat(player, message);
            else PrintError(message);
        }
        void InformAllPlayers(string langKey, params object[] args) {
            foreach (BasePlayer player in BasePlayer.activePlayerList) if (player != null) InformPlayer(player, langKey, args);
            SendDiscordMessage(langKey, args);
        }
        void InformPlayer(BasePlayer player, string langKey, params object[] args) {
            if (_config.notifyConfig.chat) PrintToChat(player, GetMessage(langKey, player.UserIDString, args));
            if (_config.supportedPluginsConfig.GUIAnnouncements.isGUIAnnouncements) GUIAnnouncements?.Call("CreateAnnouncement", ClearColorAndSize(GetMessage(langKey, player.UserIDString, args)), _config.supportedPluginsConfig.GUIAnnouncements.bannerColor, _config.supportedPluginsConfig.GUIAnnouncements.textColor, player, _config.supportedPluginsConfig.GUIAnnouncements.apiAdjustVPosition);
            if (_config.supportedPluginsConfig.notify.isNotify) player.SendConsoleCommand($"notify.show {_config.supportedPluginsConfig.notify.type} {ClearColorAndSize(GetMessage(langKey, player.UserIDString, args))}");
        }
        void SendDiscordMessage(string langKey, params object[] args) {
            if (CanSendDiscordMessage() && _config.supportedPluginsConfig.discord.keys.Contains(langKey)) {
                object fields = new[] {
                    new {
                        name = Title, value = ClearColorAndSize(GetMessage(langKey, null, args)), inline = false
                    }
                }
                ;
                DiscordMessages?.Call("API_SendFancyMessage", _config.supportedPluginsConfig.discord.webhookUrl, "", _config.supportedPluginsConfig.discord.embedColor, JsonConvert.SerializeObject(fields), null, this);
            }
        }
        string ClearColorAndSize(string message) {
            message = message.Replace("</color>", string.Empty);
            message = message.Replace("</size>", string.Empty);
            while (message.Contains("<color=")) {
                int index = message.IndexOf("<color=");
                message = message.Remove(index, message.IndexOf(">", index) - index + 1);
            }
            while (message.Contains("<size=")) {
                int index = message.IndexOf("<size=");
                message = message.Remove(index, message.IndexOf(">", index) - index + 1);
            }
            return message;
        }
        private bool CanSendDiscordMessage() => _config.supportedPluginsConfig.discord.isDiscord && !string.IsNullOrEmpty(_config.supportedPluginsConfig.discord.webhookUrl) && _config.supportedPluginsConfig.discord.webhookUrl != "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
        string GetTimeMessage(string userIDString, int seconds) {
            string message = "";
            TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
            if (timeSpan.Hours > 0) message += $" {timeSpan.Hours} {GetMessage("Hour", userIDString)}";
            if (timeSpan.Minutes > 0) message += $" {timeSpan.Minutes} {GetMessage("Min", userIDString)}";
            if (message == "") message += $" {timeSpan.Seconds} {GetMessage("Sec", userIDString)}";
            return message;
        }
#endregion Notify
#region Economy
        [PluginReference]
        readonly Plugin Economics, ServerRewards, IQEconomic;
        readonly Dictionary<ulong, double> _playersBalance = new Dictionary<ulong, double>();
        void ActionEconomy(ulong playerId, string type, string arg = "") {
            switch (type) {
                case "Crates" : double economyCrateData;
                if (_config.supportedPluginsConfig.economy.crates.TryGetValue(arg, out economyCrateData)) AddBalance(playerId, economyCrateData);
                break;
                case "Npc" : AddBalance(playerId, _config.supportedPluginsConfig.economy.npcPoint);
                break;
                case "LockedCrate" : AddBalance(playerId, _config.supportedPluginsConfig.economy.lockedCratePoint);
                break;
                case "Turret" : AddBalance(playerId, _config.supportedPluginsConfig.economy.turretPoint);
                break;
                case "Heli" : AddBalance(playerId, _config.supportedPluginsConfig.economy.heliPoint);
                break;
            }
        }
        void AddBalance(ulong playerId, double balance) {
            if (balance == 0) return;
            if (_playersBalance.ContainsKey(playerId)) _playersBalance[playerId] += balance;
            else _playersBalance.Add(playerId, balance);
        }
        void SendBalance() {
            if (!_config.supportedPluginsConfig.economy.enable || _playersBalance.Count == 0) {
                _playersBalance.Clear();
                return;
            }
            foreach (KeyValuePair<ulong, double> dic in _playersBalance) {
                if (dic.Value < _config.supportedPluginsConfig.economy.minEconomyPiont) continue;
                int intCount = Convert.ToInt32(dic.Value);
                if (_config.supportedPluginsConfig.economy.plugins.Contains("Economics") && plugins.Exists("Economics") && dic.Value > 0) Economics.Call("Deposit", dic.Key.ToString(), dic.Value);
                if (_config.supportedPluginsConfig.economy.plugins.Contains("Server Rewards") && plugins.Exists("ServerRewards") && intCount > 0) ServerRewards.Call("AddPoints", dic.Key, intCount);
                if (_config.supportedPluginsConfig.economy.plugins.Contains("IQEconomic") && plugins.Exists("IQEconomic") && intCount > 0) IQEconomic.Call("API_SET_BALANCE", dic.Key, intCount);
                BasePlayer player = BasePlayer.FindByID(dic.Key);
                if (player != null) InformPlayer(player, "SendEconomy", _config.prefix, dic.Value);
            }
            double max = 0;
            ulong winnerId = 0;
            foreach (var a in _playersBalance) {
                if (a.Value > max) {
                    max = a.Value;
                    winnerId = a.Key;
                }
            }
            if (max >= _config.supportedPluginsConfig.economy.minCommandPoint) foreach (string command in _config.supportedPluginsConfig.economy.commands) Server.Command(command.Replace("{steamid}", $"{winnerId}"));
            _playersBalance.Clear();
        }
        void DefineEventWinner() {
            var winnerPair = _playersBalance.Max(x => (float)x.Value);
            if (winnerPair.Value > 0) Interface.CallHook("OnSputnikEventWin", winnerPair.Key);
        }
#endregion Economy
#endregion Methods
#region Classes
        class EventClass {
            EventConfig eventConfig;
            Coroutine startEventCorountine;
            Coroutine eventCorountine;
            HashSet<SputnikClass> sputnikClasses = new HashSet<SputnikClass>();
            internal int eventTime;
            internal SputnikClass GetSputnikClassFromPLayerInZoneUid(ulong userId) => sputnikClasses.FirstOrDefault(x => x != null && x.IsPlayerInZone(userId));
            internal SputnikClass GetSputnikClassFromCrateUid(uint crateUID) => sputnikClasses.FirstOrDefault(x => x != null && (x.IsEventCrate(crateUID) || x.IsEventLockedCrate(crateUID)));
            internal SputnikClass GetSputnikClassFromCardReaderUid(uint cardReaderUID) => sputnikClasses.FirstOrDefault(x => x != null && x.IsClassCardReader(cardReaderUID));
            internal bool IsEventTurret(uint netID) => sputnikClasses.Any(x => x != null && x.IsDebrisTurret(netID));
            internal bool IsEventMine(uint netID) => sputnikClasses.Any(x => x != null && x.IsDebrisMine(netID));
            internal void StartEvent(EventConfig eventConfig) {
                this.eventConfig = eventConfig;
                eventTime = eventConfig.eventTime;
                startEventCorountine = ServerMgr.Instance.StartCoroutine(StartEventCorountine());
            }
            internal void StopEvent() {
                foreach (SputnikClass sputnikClass in sputnikClasses) {
                    if (sputnikClass != null && sputnikClass.gameObject != null) UnityEngine.Object.DestroyImmediate(sputnikClass.gameObject);
                }
                if (startEventCorountine != null) ServerMgr.Instance.StopCoroutine(startEventCorountine);
                if (eventCorountine != null) ServerMgr.Instance.StopCoroutine(eventCorountine);
            }
            IEnumerator StartEventCorountine() {
                if (ins._config.notifyConfig.chat) {
                    foreach (BasePlayer player in BasePlayer.activePlayerList) if (player != null) ins.InformPlayer(player, "PreStartEvent", ins._config.prefix, eventConfig.displayName, ins.GetTimeMessage(player.UserIDString, ins._config.notifyConfig.preStartTime));
                }
                ins.SendDiscordMessage("PreStartEvent", ins._config.prefix, eventConfig.displayName, ins.GetTimeMessage(null, ins._config.notifyConfig.preStartTime));
                yield return CoroutineEx.waitForSeconds(ins._config.notifyConfig.preStartTime);
                if (ins.autoEventCorountine != null) ServerMgr.Instance.StopCoroutine(ins.autoEventCorountine);
                ins.InformAllPlayers("StartEvent", ins._config.prefix, eventConfig.displayName);
                CreateNewSputnikClasses();
                eventCorountine = ServerMgr.Instance.StartCoroutine(EventCorountine());
                ins.Subscribes();
            }
            IEnumerator EventCorountine() {
                while (eventTime > 0 && sputnikClasses.Any(x => x != null)) {
                    eventTime -= 1;
                    if (ins._config.notifyConfig.chat && ins._config.notifyConfig.timeNotifications.Contains(eventTime)) {
                        foreach (BasePlayer player in BasePlayer.activePlayerList) {
                            if (player != null) ins.PrintToChat(player, ins.GetMessage("RemainTime", player.UserIDString, ins._config.prefix, eventConfig.displayName, ins.GetTimeMessage(player.UserIDString, eventTime)));
                        }
                    }
                    foreach (SputnikClass sputnikClass in sputnikClasses) sputnikClass.UpdateZone();
                    yield return CoroutineEx.waitForSeconds(1);
                }
                ins.StopEvent();
            }
            void CreateNewSputnikClasses() {
                if (eventConfig.fixedSputniksPresets != null && eventConfig.fixedSputniksPresets.Count > 0) {
                    foreach (string sputnikDebrisPresetName in eventConfig.fixedSputniksPresets) {
                        SputnikDebrisConfig sputnikDebrisConfig = ins._config.sputnikDebrisConfigs.FirstOrDefault(x => x.presetName == sputnikDebrisPresetName);
                        if (sputnikDebrisConfig == null) {
                            ins.PrintError("Sputnik debris preset not found!");
                            continue;
                        }
                        CreateNewSputnikClass(sputnikDebrisConfig);
                    }
                }
                if (sputnikClasses.Count == 0 || !sputnikClasses.Any(x => x != null)) ins.StopEvent();
            }
            void CreateNewSputnikClass(SputnikDebrisConfig sputnikDebrisConfig) {
                GameObject gameObject = new GameObject();
                gameObject.layer = (int)Layer.Reserved1;
                SputnikClass sputnik = gameObject.AddComponent<SputnikClass>();
                sputnik.Init(sputnikDebrisConfig);
                sputnikClasses.Add(sputnik);
            }
        }
        class SputnikClass : FacepunchBehaviour {
            internal SputnikDebrisConfig sputnikDebrisConfig;
            Coroutine crushEffectsCorountine;
            Coroutine onSputnikFellCorountine;
            Coroutine destroyCorountine;
            FallSputnikClass fallSputnik;
            MapMarkerGenericRadius mapmarker;
            VendingMachineMapMarker vendingMarker;
            HashSet<BaseEntity> decorEntities = new HashSet<BaseEntity>();
            HashSet<AutoTurret> turrets = new HashSet<AutoTurret>();
            HashSet<BaseEntity> mines = new HashSet<BaseEntity>();
            ZoneClass zoneClass;
            CardReader cardReader;
            SputnikHeli sputnikHeli;
            internal bool cardReaderOpen = true;
            internal HashSet<ScientistNPC> npcs = new HashSet<ScientistNPC>();
            internal HashSet<uint> openedCrates = new HashSet<uint>();
            internal Dictionary<LootContainer, string> crates = new Dictionary<LootContainer, string>();
            internal Dictionary<LootContainer, string> lockedCrates = new Dictionary<LootContainer, string>();
            internal HashSet<uint> spaceCardCratesIDs = new HashSet<uint>();
            internal int destroyTime = 0;
            internal bool IsClassCardReader(uint netId) => cardReader != null && cardReader.net.ID == netId;
            internal bool CanOpenCrate(uint netId) => !spaceCardCratesIDs.Contains(netId) || !cardReader.IsExists() || cardReaderOpen;
            internal bool IsEventCrate(uint netId) => crates.Keys.Any(x => x.IsExists() && x.net.ID == netId);
            internal bool IsEventLockedCrate(uint netId) => lockedCrates.Keys.Any(x => x.IsExists() && x.net.ID == netId);
            internal bool IsPlayerInZone(ulong userId) => zoneClass != null && zoneClass.playersInZone.Any(x => x.userID == userId);
            internal bool IsDebrisTurret(uint netId) => turrets.Any(x => x.IsExists() && x.net.ID == netId);
            internal bool IsDebrisMine(uint netId) => mines.Any(x => x.IsExists() && x.net.ID == netId);
            internal void RemovePlayerFromZone(BasePlayer player) {
                if (zoneClass == null || !zoneClass.playersInZone.Any(x => x.userID == player.userID)) return;
                zoneClass.playersInZone.Remove(player);
                if (ins._config.guiConfig.IsGUI) CuiHelper.DestroyUi(player, "SputnikGui");
                if (sputnikDebrisConfig.zoneConfig.isCreateZonePVP) ins.InformPlayer(player, "ExitPVP", ins._config.prefix);
            }
            internal void OnCratelooted(uint netId) {
                if (destroyCorountine != null || openedCrates.Contains(netId) || ins._config.mainConfig.destroyAfterLootingTime > ins.eventClass.eventTime || ins._config.mainConfig.destroyAfterLootingTime == 0) return;
                openedCrates.Add(netId);
                if (crates.Keys.Any(x => x != null && !openedCrates.Contains(x.net.ID)) || lockedCrates.Keys.Any(x => x != null && !openedCrates.Contains(x.net.ID))) return;
                destroyCorountine = ServerMgr.Instance.StartCoroutine(DestroyCorountine());
            }
            internal void Init(SputnikDebrisConfig sputnikDebrisConfig) {
                this.sputnikDebrisConfig = sputnikDebrisConfig;
                DefineEventPosition();
                CreateFallSputnik();
            }
            internal void UpdateZone() {
                UpdateMapMarker();
                if (zoneClass != null) zoneClass.UpdateGui();
            }
            void DefineEventPosition() {
                Vector3 position = Vector3.zero;
                while (position == Vector3.zero && LocationDefiner.spawnPositions.Count > 0) {
                    Vector3 newPosition = LocationDefiner.spawnPositions.GetRandom();
                    if (LocationDefiner.PostChechPoint(newPosition)) {
                        position = newPosition;
                        break;
                    }
                    else LocationDefiner.spawnPositions.Remove(newPosition);
                }
                if (position != Vector3.zero) {
                    gameObject.transform.position = position;
                    LocationDefiner.spawnPositions.Remove(position);
                }
                else {
                    ins.PrintError("The event could not be started! Increase the number of cached spawn points!");
                    ins.NextTick(() => ins.StopEvent());
                }
            }
            void CreateFallSputnik() {
                fallSputnik = gameObject.AddComponent<FallSputnikClass>();
                fallSputnik.Init(this, gameObject.transform.position);
            }
            internal void OnSputnikFell() => onSputnikFellCorountine = ServerMgr.Instance.StartCoroutine(OnSputnikFellCorountine());
            IEnumerator OnSputnikFellCorountine() {
                crushEffectsCorountine = ServerMgr.Instance.StartCoroutine(CrushEffectsCorountine());
                yield return CoroutineEx.waitForSeconds(0.5f);
                CreateGrounSputnik();
                CreateCardReader();
                CreateNPCs();
                CreateCrates();
                CreateMines();
                SpawnMarkers();
                CreateHeli();
                CreateTurrets();
                CreateZone();
                yield return CoroutineEx.waitForSeconds(2f);
                if (fallSputnik != null) Destroy(fallSputnik);
                ins.InformAllPlayers("Crash", ins._config.prefix, PhoneController.PositionToGridCoord(gameObject.transform.position));
            }
            IEnumerator CrushEffectsCorountine() {
                for (int i = 0; i < ins._config.fallindConfig.countEffects; i++) {
                    Effect.server.Run("assets/bundled/prefabs/fx/explosions/explosion_03.prefab", gameObject.transform.position + new Vector3(UnityEngine.Random.Range(-7.5f, 7.5f), 0, UnityEngine.Random.Range(-7.5f, 7.5f)));
                    Effect.server.Run("assets/bundled/prefabs/fx/explosions/explosion_02.prefab", gameObject.transform.position + new Vector3(UnityEngine.Random.Range(-7.5f, 7.5f), 0, UnityEngine.Random.Range(-7.5f, 7.5f)));
                    yield return CoroutineEx.waitForSeconds(0.1f);
                }
            }
            IEnumerator DestroyCorountine() {
                destroyTime = ins._config.mainConfig.destroyAfterLootingTime;
                UpdateZone();
                while (destroyTime > 1) {
                    destroyTime -= 1;
                    yield return CoroutineEx.waitForSeconds(1);
                }
                UnityEngine.Object.DestroyImmediate(this.gameObject);
            }
            void CreateZone() {
                zoneClass = gameObject.AddComponent<ZoneClass>();
                zoneClass.Init(this);
            }
            void SpawnMarkers() {
                if (!sputnikDebrisConfig.markerConfig.enable) return;
                SpawnMapMarker();
                SpawnVendingMarker();
            }
            void SpawnMapMarker() {
                mapmarker = GameManager.server.CreateEntity("assets/prefabs/tools/map/genericradiusmarker.prefab", gameObject.transform.position) as MapMarkerGenericRadius;
                mapmarker.enableSaving = false;
                mapmarker.Spawn();
                mapmarker.radius = sputnikDebrisConfig.markerConfig.radius;
                mapmarker.alpha = sputnikDebrisConfig.markerConfig.alpha;
                mapmarker.color1 = new Color(sputnikDebrisConfig.markerConfig.color1.r, sputnikDebrisConfig.markerConfig.color1.g, sputnikDebrisConfig.markerConfig.color1.b);
                mapmarker.color2 = new Color(sputnikDebrisConfig.markerConfig.color2.r, sputnikDebrisConfig.markerConfig.color2.g, sputnikDebrisConfig.markerConfig.color2.b);
            }
            void SpawnVendingMarker() {
                vendingMarker = GameManager.server.CreateEntity("assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab", gameObject.transform.position) as VendingMachineMapMarker;
                vendingMarker.enableSaving = false;
                vendingMarker.markerShopName = $"{sputnikDebrisConfig.markerConfig.displayName} {ins.GetTimeMessage(null, ins.eventClass.eventTime)}";
                vendingMarker.Spawn();
            }
            void UpdateMapMarker() {
                if (vendingMarker != null) {
                    string text = destroyTime > 0 ? $"{sputnikDebrisConfig.markerConfig.displayName} {ins.GetTimeMessage(null, destroyTime)}" : $"{sputnikDebrisConfig.markerConfig.displayName} {ins.GetTimeMessage(null, ins.eventClass.eventTime)}";
                    vendingMarker.markerShopName = text;
                    vendingMarker.SendNetworkUpdate();
                }
         
// ... [Code preview truncated due to length. Full source in attached file] ...

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