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

FREE Quest : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins;
using UnityEngine;
using UnityEngine.XR;
namespace Oxide.Plugins {
    [Info("Quest", "Hougan", "1.0.0")]
    public class Quest : RustPlugin {
#region Classes
        private class DResult {
            [JsonProperty("code")]
            public int Code;
            [JsonProperty("result")]
            public object Result;
            public static DResult GenerateFromAnswer(string input, string id, string type) {
                DResult obj = null;
                try {
                    obj = JsonConvert.DeserializeObject<DResult>(input);
                }
                catch(Exception exception) {
                    _.LogToFile("QuestErrors", input, _);
                    Interface.Oxide.LogWarning($"WEB> Critical error in getting result from server [{id}][{type}]");
                }
                return obj;
            }
        }
        private class DPart {
            [JsonProperty("id")]
            public int Id;
            [JsonProperty("name")]
            public string Name;
            [JsonProperty("url")]
            public string Url;
            [JsonProperty("smallUrl")]
            public string SmallUrl;
            [JsonProperty("amount")]
            public int Amount;
            [JsonProperty("command")]
            public string Command;
            [JsonProperty("item")]
            public string Item;
            public string GetImage() => (string) _.ImageLibrary.Call("GetImage", $"PartsID.{Id}.Avatar");
            public string GetSmallImage() => (string) _.ImageLibrary.Call("GetImage", $"PartsID.{Id}.SmallAvatar");
            public static void LoadParts() {
                _.webrequest.Enqueue($"{Settings.WebURL}/api/parts/fetch?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    DResult result = DResult.GenerateFromAnswer(s, "0", "parts");
                    if (result == null) {
                        return;
                    }
                    HashSet<DPart> info = JsonConvert.DeserializeObject<HashSet<DPart>>(result.Result.ToString());
                    Parts = info;
                    if (!_.ImageLibrary) {
                        _.PrintError($"C#> Failed to load images [ERROR]");
                        return;
                    }
                    _.PrintWarning($"WEB> Loaded {info.Count} parts [OK]");
                    foreach (var part in info) {
                        _.ImageLibrary.Call("AddImage", part.Url, $"PartsID.{part.Id}.Avatar");
                        _.ImageLibrary.Call("AddImage", part.SmallUrl, $"PartsID.{part.Id}.SmallAvatar");
                    }
                }
                , _);
            }
        }
        private class DPlayer {
            [JsonProperty("id")]
            public int Id;
            [JsonProperty("displayName")]
            public string DisplayName;
            [JsonProperty("userId")]
            public ulong UserID;
            [JsonProperty("exp")]
            public float Exp;
            [JsonProperty("level")]
            public float Level;
            [JsonProperty("free")]
            public bool Free;
            [JsonProperty("players@items")]
            public List<DItemCache> InventoryCaches = new List<DItemCache>();
            [JsonIgnore]
            public HashSet<DItem> Inventory = new HashSet<DItem>();
            [JsonProperty("players@blockeditems")]
            public List<DItem> Blocked = new List<DItem>();
            [JsonProperty("murders")]
            public List<DMurder> Murders = new List<DMurder>();
            [JsonProperty("quest")]
            public DQuest Quest = new DQuest();
            public void DebugInformation() {
                Interface.Oxide.LogWarning($"ID: {Id}");
                Interface.Oxide.LogWarning($"Name: {DisplayName}");
                Interface.Oxide.LogWarning($"UserID: {UserID}");
                Interface.Oxide.LogWarning($"");
                Interface.Oxide.LogWarning($"EXP: {Exp}");
                Interface.Oxide.LogWarning($"Level: {Level}");
                Interface.Oxide.LogWarning($"");
                Interface.Oxide.LogWarning($"Inventory count: {Inventory.Count}");
                Interface.Oxide.LogWarning($"Murders count: {Murders.Count}");
                Interface.Oxide.LogWarning($"Active quest: {Quest != null}");
            }
            public void RefreshIDs() {
                foreach (var check in Inventory) {
                    check.OutID = CuiHelper.GetGuid();
                }
            }
            public void FinishQuest(Action<bool> callback, bool manual = false) {
                if (Quest == null || !Quest.IsEnd()) return;
                _.webrequest.Enqueue($"{Settings.WebURL}/api/players/finishQuest/{UserID}/{manual}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    UpdateAfterUpdate(s);
                    callback(true);
                }
                , _);
            }
            public void GenerateQuest(DMurder murder, Action<bool> callback) {
                if (Quest != null) {
                    callback(false);
                    return;
                }
                var player = BasePlayer.Find(UserID.ToString());
                float length = Settings.TaskPrice[murder.Level].Length;
                if (murder.Level == 4) {
                    length = Mathf.FloorToInt(Oxide.Core.Random.Range(600, 7200));
                }
                _.webrequest.Enqueue($"{Settings.WebURL}/api/players/setQuest/{UserID}/{murder.Level}/{length}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    UpdateAfterUpdate(s);
                    player.GetComponent<WPlayer>().SendExpUpdate();
                    callback(true);
                }
                , _);
            }
            public static void GetFromPlayer(BasePlayer player, Action<DPlayer> callback) {
                GetFromPlayer(player.displayName, player.userID, callback);
            }
            public static void GetFromPlayer(string displayName, ulong userId, Action<DPlayer> callback) {
                _.webrequest.Enqueue($"{Settings.WebURL}/api/players/fetch/{userId}/FIX?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    try {
                        var result = DResult.GenerateFromAnswer(s, userId.ToString(), "fetch player");
                        if (result == null) {
                            return;
                        }
                        var info = DPlayer.GenerateFromAnswer(result.Result as JObject);
                        if (info == null) {
                            return;
                        }
                        callback(info);
                    }
                    catch {
                    }
                }
                , _);
            }
            public void UpdateAfterUpdate(string s) {
                var result = DResult.GenerateFromAnswer(s, UserID.ToString(), "update after update");
                if (result == null) {
                    return;
                }
                var info = DPlayer.GenerateFromAnswer(result.Result as JObject);
                if (info == null) {
                    return;
                }
                _.UpdatePlayer(BasePlayer.Find(UserID.ToString()), info);
            }
            public static DPlayer GenerateFromAnswer(JObject obj) {
                DPlayer result = null;
                try {
                    result = JsonConvert.DeserializeObject<DPlayer>(obj.ToString());
                    result.Murders.ForEach(p => p.LoadImage());
                }
                catch {
                }
                return result;
            }
        }
        private class WPlayer : MonoBehaviour {
            public BasePlayer Player;
            public float Exp;
            public int PlayTime;
            public Vector3 LastPosition;
            public HashSet<ulong> KillTarget = new HashSet<ulong>();
            public void Awake() {
                Player = GetComponent<BasePlayer>();
                LastPosition = Player.transform.position;
                InvokeRepeating(nameof(ScanPosition), 0f, 5f);
                InvokeRepeating(nameof(ClearTargetList), 0f, 1200f);
            }
            public void ClearTargetList() {
                KillTarget.Clear();
            }
            public void ScanPosition() {
                if (!Player.IsConnected) {
                    Destroy(this);
                    return;
                }
                if (Vector3.Distance(Player.transform.position, LastPosition) < 0.5f) return;
                LastPosition = Player.transform.position;
                PlayTime += 5;
                if (PlayTime == 60) {
                    PlayTime = 0;
                    List<string> names = new List<string> {
                        "bloodrust", "blood-rust", "blood rust"
                    }
                    ;
                    if (names.Any(p => Player.displayName.ToLower().Contains(p.ToLower()))) {
                        AddExp(Settings.ExpForMinute * 2f, "За одну минуту игры на сервере");
                    }
                    else {
                        AddExp(Settings.ExpForMinute, "За одну минуту игры на сервере");
                    }
                }
            }
            public bool AddExp(float amount, string mess, ulong playerId = 0) {
                if (IsInvoking(nameof(SendExpUpdate))) CancelInvoke(nameof(SendExpUpdate));
                if (playerId != 0) {
                    if (KillTarget.Contains(playerId)) {
                        //Player.ChatMessage("Вы его уже убивали!");
                        return false;
                    }
                    KillTarget.Add(playerId);
                }
                Exp += amount;
                if (Settings.DebugErrors) Player.ChatMessage($"Add {amount}exp for {mess}");
                Invoke(nameof(SendExpUpdate), 5f);
                return true;
            }
            public void SendExpUpdate() {
                try {
                    _.webrequest.Enqueue($"{Settings.WebURL}/api/players/addExp/{Player.userID}/{Exp}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                        try {
                            float value = 0;
                            if (Player == null || !float.TryParse(s, out value)) {
                                return;
                            }
                            Exp = 0;
                            Base[Player].Exp = value;
                            UpdateExpCounter(Player, ExpAction.Minus, Base[Player].Exp);
                        }
                        catch {
                        }
                    }
                    , _);
                }
                catch {
                }
            }
        }
        private class DQuest {
            [JsonProperty("id")]
            public int Id;
            [JsonProperty("timeStart")]
            public double TimeStart;
            [JsonProperty("timeEnd")]
            public double TimeEnd;
            [JsonProperty("items")]
            public List<DItem> Items = new List<DItem>();
            [JsonProperty("murder")]
            public DMurder Murder = new DMurder();
            public bool IsEnd() => Time() > TimeEnd / 1000;
            public double TimeLeft() => IsEnd() ? 0 : TimeSpan.FromSeconds(TimeEnd / 1000 - Time()).TotalSeconds;
            public string TimeLeftText() {
                if (IsEnd()) {
                    return "КОНЕЦ";
                }
                string text = "<b>";
                var timeSpan = TimeSpan.FromSeconds(TimeEnd / 1000 - Time());
                if (timeSpan.Hours > 0) return $"<b>{timeSpan.Hours} ЧАС</b>";
                if (timeSpan.Minutes > 0) return $"<b>{timeSpan.Minutes} МИН</b>";
                if (timeSpan.Seconds > 0) return $"<b>{timeSpan.Seconds} СЕК</b>";
                return "<b>0 СЕК</b>";
            }
        }
        private class DMurder {
            [JsonProperty("id")]
            public int Id;
            [JsonProperty("name")]
            public string Name;
            [JsonProperty("url")]
            public string Url;
            [JsonProperty("level")]
            public int Level;
            [JsonIgnore]
            public string ImageID;
            public void LoadImage() {
                ImageID = (string) _.ImageLibrary.Call("GetImage", $"MurderID.{Id}.Avatar");
            }
            public static void LoadImages() {
                _.webrequest.Enqueue($"{Settings.WebURL}/api/murders/fetch?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    DResult result = DResult.GenerateFromAnswer(s, "UNKNOWN", "murders fetch");
                    if (result == null) {
                        return;
                    }
                    var info = JsonConvert.DeserializeObject<List<DMurder>>(result.Result.ToString());
                    if (!_.ImageLibrary) {
                        _.PrintError($"C#> Failed to load images [ERROR]");
                        return;
                    }
                    _.PrintWarning($"WEB> Loaded {info.Count} murders [OK]");
                    foreach (var murder in info) {
                        _.ImageLibrary.Call("AddImage", murder.Url, $"MurderID.{murder.Id}.Avatar");
                    }
                }
                , _);
            }
        }
        private class DItemCache {
            public int id {
                get;
                set;
            }
            public DateTime createdAt {
                get;
                set;
            }
            public DateTime updatedAt {
                get;
                set;
            }
            public int playerId {
                get;
                set;
            }
            public int itemId {
                get;
                set;
            }
        }
        private class DItem {
            [JsonProperty("id")]
            public int Id;
            [JsonProperty("shortName")]
            public string ShortName;
            [JsonProperty("skinId")]
            public ulong SkinID;
            [JsonProperty("amount")]
            public int Amount;
            [JsonProperty("exp")]
            public float Exp;
            [JsonProperty("expBuy")]
            public float ExpBuy;
            [JsonProperty("levelQuest")]
            public int LevelQuest;
            [JsonProperty("category")]
            public string Category;
            [JsonProperty("isPart")]
            public string IsPart;
            [JsonProperty("isBp")]
            public bool IsBlueprint;
            [JsonProperty("url")]
            public string Url;
            [JsonProperty("shouldBlock")]
            public bool ShouldBlock;
            [JsonIgnore]
            public string OutID = "UNKNOWN";
            public static DItem FromCache(DItemCache cache) {
                var rItem = Market.FirstOrDefault(p => p.Id == cache.itemId);
                if (rItem == null) {
                    _.PrintError($"Unknown item {cache.itemId} -> {cache.playerId} [{cache.id}]!");
                    return Market.FirstOrDefault();
                }
                return (DItem) rItem.Clone();
            }
            public string GetImage() {
                if (ShortName.StartsWith("command: ")) {
                    return (string) _.ImageLibrary.Call("GetImage", "M.Custom." + Id);
                }
                else if (IsPart.Length < 2) {
                    return (string) _.ImageLibrary.Call("GetImage", ShortName);
                }
                else {
                    return (string) Parts.FirstOrDefault(p => p.Name == IsPart).GetSmallImage();
                }
            }
            /// <summary>
            /// Отображает процесс произведения процесса (что!?)
            /// </summary>
            private void ShowWaitingResult(BasePlayer player, bool success) {
                CuiElementContainer container = new CuiElementContainer();
                CuiHelper.DestroyUi(player, InitialLayer + $".HRPStore{OutID}.Wait");
                container.Add(new CuiButton {
                    RectTransform = {
                        AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "15 15", OffsetMax = "-15 -15"
                    }
                    , Button = {
                        Color = "1 1 1 0.5", Sprite = success ? "assets/icons/vote_up.png" : "assets/icons/vote_up.png"
                    }
                    , Text = {
                        Text = ""
                    }
                }
                , InitialLayer + $".HRPStore{OutID}", InitialLayer + $".HRPStore{OutID}.Wait");
                CuiHelper.AddUi(player, container);
            }
            /// <summary>
            /// Отображает процесс произведения процесса (что!?)
            /// </summary>
            private void WaitForResponseOnItem(BasePlayer player) {
                CuiElementContainer container = new CuiElementContainer();
                CuiHelper.DestroyUi(player, InitialLayer + $".HRPStore{OutID}.Overflow");
                container.Add(new CuiElement {
                    Parent = InitialLayer + $".HRPStore{OutID}", Components = {
                        new CuiRawImageComponent {
                            Png = WhiteLockerImage, Color = "1 1 1 0.3"
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                        }
                    }
                }
                );
                container.Add(new CuiButton {
                    RectTransform = {
                        AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "15 15", OffsetMax = "-15 -15"
                    }
                    , Button = {
                        Color = "1 1 1 0.5", Sprite = "assets/icons/refresh.png"
                    }
                    , Text = {
                        Text = ""
                    }
                }
                , InitialLayer + $".HRPStore{OutID}", InitialLayer + $".HRPStore{OutID}.Wait");
                CuiHelper.AddUi(player, container);
            }
            public void Buy(BasePlayer player, DPlayer dPlayer) {
                _.webrequest.Enqueue($"{Settings.WebURL}/api/players/buyItem/{dPlayer.UserID}/{Id}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    DResult result = DResult.GenerateFromAnswer(s, dPlayer.UserID.ToString(), "but item");
                    if (result == null) {
                        return;
                    }
                    if (result.Result is Boolean) {
                        dPlayer.Exp -= ExpBuy;
                        UpdateExpCounter(player, ExpAction.Minus, dPlayer.Exp);
                        dPlayer.Inventory.Add((DItem) Clone());
                        if (ShouldBlock) {
                            dPlayer.Blocked.Add((DItem) Clone());
                        }
                        _.InitializeShop(player, dPlayer);
                        Effect effect = new Effect("assets/prefabs/deployable/vendingmachine/effects/vending-machine-purchase-human.prefab", player, 0, new Vector3(), new Vector3());
                        EffectNetwork.Send(effect, player.Connection);
                    }
                    else {
                        //LogError($"C#> Не удалось купить {ShortName} [{Id}] игрком {dPlayer.UserID}.Причина: '{result.Result}'");
                    }
                }
                , _);
            }
            public void RefundItem(BasePlayer player, DPlayer dPlayer) {
                WaitForResponseOnItem(player);
                _.webrequest.Enqueue($"{Settings.WebURL}/api/players/removeItem/{dPlayer.UserID}/{Id}/{Exp}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    DResult result = DResult.GenerateFromAnswer(s, dPlayer.UserID.ToString(), "refund item");
                    if (result == null) {
                        return;
                    }
                    if (result.Result is Boolean) {
                        dPlayer.Exp += Exp;
                        ShowWaitingResult(player, (bool) result.Result);
                        UpdateExpCounter(player, ExpAction.Plus, dPlayer.Exp);
                        dPlayer.Inventory.Remove(this);
                    }
                    else {
                        LogError($"C#> Не удалось вернуть {ShortName} [{Id}] игрком {dPlayer.UserID}.Причина: '{result.Result}'");
                    }
                }
                , _);
            }
            public void ProcessItem(BasePlayer player, DPlayer dPlayer) {
                WaitForResponseOnItem(player);
                dPlayer.Inventory.Remove(this);
                _.webrequest.Enqueue($"{Settings.WebURL}/api/players/removeItem/{dPlayer.UserID}/{Id}/false?pass=ABCBLOO1ss1009g", "", (i, s) => {
                    DResult result = DResult.GenerateFromAnswer(s, dPlayer.UserID.ToString(), "process item");
                    if (result == null) {
                        return;
                    }
                    if (result.Result is Boolean) {
                        ShowWaitingResult(player, (bool) result.Result);
                        Item item = null;
                        Effect effect = new Effect("assets/bundled/prefabs/fx/notice/stack.world.fx.prefab", player, 0, new Vector3(), new Vector3());
                        EffectNetwork.Send(effect, player.Connection);
                        if (ShortName != "") {
                            if (ShortName.StartsWith("command: ")) {
                                string cmd = ShortName.Replace("command: ", "").Replace("%STEAMID%", player.UserIDString);
                                _.Server.Command(cmd);
                                if (cmd.StartsWith("grant")) {
                                    _.webrequest.Enqueue($"http://api2.hougan.space/blood/rcon/{cmd}/2281337ABC/all?pass=ABCBLOO1ss1009g", "", (i1, s1) => {
                                    }
                                    , _);
                                }
                            }
                            else {
                                if (IsBlueprint) {
                                    item = ItemManager.CreateByItemID(-996920608, 1, 0);
                                    item.blueprintTarget = ItemManager.FindItemDefinition(ShortName).itemid;
                                }
                                else {
                                    item = ItemManager.CreateByName(ShortName, Amount, SkinID);
                                }
                                if (!item.MoveToContainer(player.inventory.containerMain)) item.Drop(player.transform.position, Vector3.zero);
                                player.SendConsoleCommand($"note.inv {item.info.itemid} {item.amount}");
                            }
                        }
                    }
                    else {
                        LogError($"C#> Не удалось получить {ShortName} [{Id}] игрком {dPlayer.UserID}.Причина: '{result.Result}'");
                    }
                }
                , _);
            }
            public object Clone() {
                return new DItem {
                    Amount = Amount, Category = Category, Exp = Exp, Id = Id, ExpBuy = ExpBuy, IsPart = IsPart, IsBlueprint = IsBlueprint, LevelQuest = LevelQuest, ShortName = ShortName, OutID = CuiHelper.GetGuid(), SkinID = SkinID
                }
                ;
            }
        }
        public class LevelSettings {
            [JsonProperty("Стоимость наёмника в EXP")]
            public int ExpCost;
            [JsonProperty("Длительность поиска (сек.)")]
            public int Length;
            [JsonProperty("Минимальное количество предметов")]
            public int MinimalItems;
            [JsonProperty("Максимальное количество предметов")]
            public int MaximumItems;
        }
        private class Configuration {
            public bool DebugErrors = true;
            public string WebURL = "http://mercenaries.bloodrust.ru/";
            [JsonProperty("Настройки уровней для поиска наёмников")]
            public Dictionary<int, LevelSettings> TaskPrice = new Dictionary<int, LevelSettings>();
            [JsonProperty("Получение EXP за добычу ресурсов")]
            public Hash<string, float> ResourceExp = new Hash<string, float>();
            [JsonProperty("Получение EXP за посадку ресурсов")]
            public Hash<string, float> PlantExp = new Hash<string, float>();
            [JsonProperty("Получение EXP за убийство (разрушения)")]
            public Hash<string, float> KillExp = new Hash<string, float>();
            [JsonProperty("Получение EXP за открытие ящиков")]
            public Hash<string, float> LootExp = new Hash<string, float>();
            [JsonProperty("Получение EXP за постройки")]
            public Hash<string, float> BuildExp = new Hash<string, float>();
            [JsonProperty("EXP за минуту игры на сервере")]
            public float ExpForMinute = 0.5f;
            public static Configuration Generate() {
                return new Configuration {
                    DebugErrors = true, ResourceExp = new Hash<string, float> {
                        ["sulfur-ore"]
                        = 0.05f, ["tree"] = 10f
                    }
                    , PlantExp = new Hash<string, float> {
                    }
                    , BuildExp = new Hash<string, float> {
                        ["tier1"]
                        = 1f, ["tier2"] = 1f, ["tier3"] = 1f, ["tier4"] = 1f,
                    }
                    , KillExp = new Hash<string, float> {
                        ["player"]
                        = 1f, ["tier1"] = 1f, ["tier2"] = 1f, ["tier3"] = 1f, ["tier4"] = 1f,
                    }
                    , LootExp = new Hash<string, float> {
                    }
                    , ExpForMinute = 0.5f, TaskPrice = new Dictionary<int, LevelSettings> {
                        [1]
                        = new LevelSettings {
                            ExpCost = 10, Length = 1000, MinimalItems = 1, MaximumItems = 5
                        }
                        , [2] = new LevelSettings {
                            ExpCost = 20, Length = 1, MinimalItems = 1, MaximumItems = 5
                        }
                        , [3] = new LevelSettings {
                            ExpCost = 30, Length = 1, MinimalItems = 1, MaximumItems = 5
                        }
                        , [4] = new LevelSettings {
                            ExpCost = 40, Length = 1, MinimalItems = 1, MaximumItems = 5
                        }
                    }
                }
                ;
            }
        }
#endregion
#region Variables
        private static bool CheckEngine = false;
        private static Hash<ulong, float> CheckData = new Hash<ulong, float>();
        private static bool Initialized = false;
        private static Quest _;
        private enum ExpAction {
            None, Plus, Minus
        }
        [PluginReference]
        private Plugin ImageLibrary;
        private static string BlueprintImage;
        private static string LockerImage;
        private static string WhiteLockerImage;
        private static string HandlerCommand = "UI_Quest_FuryController";
        private static HashSet<ulong> Joined = new HashSet<ulong>();
        private static HashSet<DPart> Parts = new HashSet<DPart>();
        private static HashSet<DItem> Market = new HashSet<DItem>();
        private static Configuration Settings;
        private static Hash<BasePlayer, DPlayer> Base = new Hash<BasePlayer, DPlayer>();
        private static Hash<BasePlayer, WPlayer> Workers = new Hash<BasePlayer, WPlayer>();
        private static Hash<BaseEntity, ulong> Tankers = new Hash<BaseEntity, ulong>();
        private static Hash<ulong, double> SyncCooldowns = new Hash<ulong, double>();
        private static Dictionary<string, string> Sections = new Dictionary<string, string> {
            ["FURY"]
            = "НАЁМНИКИ", ["STORE"] = "ЯЩИК НАЁМНИКОВ", ["SHOP"] = "РЫНОК", ["PARTS"] = "СБОР ФРАГМЕНТОВ",
        }
        ;
#endregion
#region Hooks
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                Settings = Config.ReadObject<Configuration>();
            }
            catch {
                PrintWarning($"Error reading config, creating one new config!");
                LoadDefaultConfig();
            }
            SaveConfig();
        }
        protected override void LoadDefaultConfig() => Settings = Configuration.Generate();
        protected override void SaveConfig() => Config.WriteObject(Settings);
        private void FetchBaseSync(Action callback) {
            DPlayer.GetFromPlayer("TEST_BORDER", 2281337, dPlayer => {
                PrintWarning("WEB> Testing account found [OK]");
                _.timer.Once(1, DPart.LoadParts);
                _.timer.Once(2, DMurder.LoadImages);
                _.timer.Once(3, FetchMurders);
                _.timer.Once(4, LoadImages);
                _.timer.Once(6, FetchMarket);
                _.timer.Once(30, callback);
            }
            );
        }
        private IEnumerator LoadGlobalPlayers() {
            foreach (var check in BasePlayer.activePlayerList) {
                int index = BasePlayer.activePlayerList.ToList().IndexOf(check);
                if (index % 5 == 0) PrintWarning($"WEB> Loaded {(float) index / BasePlayer.activePlayerList.Count}% loaded [OK]");
                OnPlayerConnected(check);
                yield return new WaitForSeconds(0.25f);
            }
            Initialized = true;
            yield return 0;
        }
        private void SaveData() {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/CheckEngine", CheckData);
        }
        private void OnServerInitialized() {
            _ = this;
            if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/CheckEngine")) CheckData = Interface.Oxide.DataFileSystem.ReadObject<Hash<ulong, float>>($"{Name}/CheckEngine");
            timer.Every(60, SaveData);
            if (CheckEngine) {
                PrintError("Аварийный режим, вам на разборочку");
                return;
            }
            timer.Once(1, () => {
                FetchBaseSync(() => {
                    timer.Every(5, () => {
                        foreach (var check in Base) {
                            if (check.Value.Quest != null && check.Value.Quest.TimeEnd / 1000 < Time()) {
                                if (check.Value.Quest.Murder.Level != 4) {
                                    Interface.Oxide.CallHook("AddNotification", check.Key, $"{check.Value.Quest.Murder.Name.ToUpper()} ВЕРНУЛСЯ", $"Нажмите чтобы посмотреть найденные предметы", "1 1 1 0.5", 10, "", "", "chat.say /fury");
                                }
                                else {
                                    Interface.Oxide.CallHook("AddNotification", check.Key, $"{check.Value.Quest.Murder.Name.ToUpper()} ОТКРЫТ", $"Нажмите чтобы посмотреть полученные предметы", "1 1 1 0.5", 10, "", "", "chat.say /fury");
                                }
                            }
                        }
                    }
                    );
                    timer.Every(5, () => {
                        if (Market.Count == 0) {
                            FetchBaseSync(null);
                        }
                    }
                    );
                    PrintError("Загрузка успешно окончена!");
                }
                );
            }
            );
        }
        private void OnPlayerConnected(BasePlayer player) {
            FetchPlayer(player);
        }
        private void OnPlayerDisconnected(BasePlayer player, string reason) => DestroyPlayer(player);
        private void Unload() => BasePlayer.activePlayerList.ToList().ToList().ToList().ForEach(DestroyPlayer);
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
            if ((entity.PrefabName.Contains("patrol") || entity.PrefabName.Contains("bradley") || entity.PrefabName.Contains("ch47")) && info?.InitiatorPlayer != null && Base.ContainsKey(info.InitiatorPlayer)) {
                entity._name = info.InitiatorPlayer.UserIDString ?? "UNKNOWN";
            }
        }
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
            if (entity == null || info == null) return;
            var player = info.InitiatorPlayer;
            if (player == null || !Base.ContainsKey(player)) {
                if (entity._name?.Length == 17) {
                    player = BasePlayer.Find(entity._name);
                }
                if (player == null || !Base.ContainsKey(player)) return;
            }
            string shortName = entity.ShortPrefabName;
            if (entity is BuildingBlock) shortName = "tier" + (int) ((entity as BuildingBlock).grade);
            var amount = 0f;
            if (!Settings.KillExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [ED]: " + shortName);
                }
                return;
            }
            if ((entity is BasePlayer && ((BasePlayer) entity).userID == player.userID)) return;
            player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color>\"");
            AddEXP(player, amount, "Убийство " + shortName, entity.GetComponent<BasePlayer>() != null ? ((BasePlayer) entity).userID : 0);
        }
        private void OnCardSwipe(CardReader cardReader, Keycard card, BasePlayer player) {
            if (player == null || card.accessLevel != cardReader.accessLevel) return;
            var amount = 0f;
            if (!Settings.BuildExp.TryGetValue($"card{card.accessLevel}", out amount)) {
                //Server.Command($"echo card{card.accessLevel}");
                if (Settings.DebugErrors) {
                    player.ChatMessage("Неизвестный тип [EB]: " + $"echo card{card.accessLevel}");
                }
                return;
            }
            player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color>\"");
            AddEXP(player, amount, "Свайп " + $"echo card{card.accessLevel}");
        }
        private void OnEntityBuilt(Planner plan, GameObject go) {
            var player = plan.GetOwnerPlayer();
            var ent = go.ToBaseEntity();
            if (player == null || ent == null) return;
            string shortName = go.ToBaseEntity().ShortPrefabName;
            var amount = 0f;
            if (!Settings.BuildExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [EB]: " + shortName);
                }
                return;
            }
            var planItem = plan?.GetItem();
            if (planItem != null) {
                if (planItem.skin != 0) {
                    return;
                }
            }
            player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color>\"");
            AddEXP(player, amount, "Постройка " + shortName);
        }
        private void OnLootEntity(BasePlayer player, BaseEntity entity) {
            if (entity.name == "LOOTED") return;
            entity.name = "LOOTED";
            string shortName = entity.ShortPrefabName;
            var amount = 0f;
            if (!Settings.LootExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [EB]: " + shortName);
                }
                return;
            }
            player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color>\"");
            AddEXP(player, amount, "Постройка " + shortName);
        }
        private void CanAffordUpgrade(BasePlayer player, BuildingBlock block, BuildingGrade.Enum grade) {
            if (player == null) return;
            string shortName = "tier" + (int) grade;
            var amount = 0f;
            if (!Settings.BuildExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [AU]: " + shortName);
                }
                return;
            }
            player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color>\"");
            AddEXP(player, amount, "Улучшение " + shortName);
        }
        private void OnCollectiblePickup(Item item, BasePlayer player, CollectibleEntity entity) {
            string shortName = entity.GetComponent<BaseEntity>().ShortPrefabName;
            var amount = 0f;
            if (!Settings.ResourceExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [CP]: " + shortName);
                }
                return;
            }
            if (AddEXP(player, amount, "[CP] Добыча " + shortName, entity.net.ID)) {
                item.name = item.info.displayName.english + $" <size=10><color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color></size>";
                NextTick(() => {
                    item.name = "";
                }
                );
            }
        }
        private void OnDispenserBonus(ResourceDispenser dispenser, BasePlayer player, Item item) {
            string shortName = dispenser.GetComponent<BaseEntity>().ShortPrefabName;
            if (item.info.shortname == "wood") shortName = "tree";
            if (item.info.shortname == "sulfur.ore") shortName = "sulfur-ore";
            if (item.info.shortname == "metal.ore") shortName = "metal-ore";
            if (item.info.shortname == "stones") shortName = "stones";
            var amount = 0f;
            if (!Settings.ResourceExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [DB]: " + shortName);
                }
                return;
            }
            if (AddEXP(player, amount, "[DP]  Добыча " + shortName, dispenser.GetComponent<BaseEntity>().net.ID)) {
                player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color>\"");
            }
            return;
        }
        private void OnGrowableGather(GrowableEntity plant, Item item, BasePlayer player) {
            string shortName = plant.ShortPrefabName;
            var amount = 0f;
            if (!Settings.ResourceExp.TryGetValue(shortName, out amount)) {
                if (Settings.DebugErrors) {
                    Server.Command($"echo {shortName}");
                    player.ChatMessage("Неизвестный тип [CG]: " + shortName);
                }
                return;
            }
            item.name = item.info.displayName.english + $" <size=10><color=#d4d8ca>+{amount}</color><color=#b9bdaf>EXP</color></size>";
            NextTick(() => {
                item.name = "";
            }
            );
            AddEXP(player, amount, "[CG] Добыча " + shortName);
        }
#endregion
#region Debug
        [ConsoleCommand("exp_merge")]
        private void CmdConsole(ConsoleSystem.Arg args) {
            if (args.Player() != null) return;
            foreach (var check in CheckData) {
                webrequest.Enqueue($"{Settings.WebURL}/api/players/addExp/{check.Key}/{check.Value}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                }
                , _);
            }
            PrintError($"Merged {CheckData.Count} pl., total: {CheckData.Sum(p => p.Value).ToString("F2")} EXP");
            CheckData.Clear();
        }
        [ChatCommand("update.items")]
        private void CmdChat(BasePlayer player) {
            if (!player.IsAdmin) return;
            ServerMgr.Instance.StartCoroutine(LoadingQueue());
        }
        private IEnumerator LoadingQueue() {
            var list = ItemManager.itemList.Where(p => p.Blueprint != null && p.Blueprint.isResearchable && p.Blueprint.workbenchLevelRequired > 0 && p.Blueprint.userCraftable);
            foreach (var check in list) {
                PrintError($"Loaded ok: {check.shortname}");
                webrequest.Enqueue($"{Settings.WebURL}api/items/add/{check.shortname}/0/{check.stackable}/{check.stackable}/{check.Blueprint.workbenchLevelRequired}/caban/{check.category.ToString()}?pass=ABCBLOO1ss1009g", "", (i, s) => {
                }
                , this);
                yield return new WaitForSeconds(0.2f);
            }
        }
#region EXP Money
        [ChatCommand("exp.none")]
        private void CmdChatExpNone(BasePlayer player) {
            Item item = ItemManager.CreateByPartialName("scraptransportheli.repair");
            item.MoveToContainer(player.inventory.containerBelt);
            UpdateExpCounter(player, ExpAction.None, 1488);
        }
        [ChatCommand("exp.plus")]
        private void CmdChatExpPlus(BasePlayer player) => UpdateExpCounter(player, ExpAction.Plus, 1488);
        [ChatCommand("exp.minus")]
        private void CmdChatExpMinus(BasePlayer player) => UpdateExpCounter(player, ExpAction.Minus, 1488);
#endregion
#endregion
#region Methods
        private bool AddEXP(BasePlayer player, float amount, string mess = "", ulong targetId = 0) {
            //player.SendConsoleCommand($"note.inv 605467368 1 \"<color=#83c786>+{amount}EXP</color>\"");
            if (CheckEngine) {
                if (!CheckData.ContainsKey(player.userID)) CheckData.Add(player.userID, 0f);
                CheckData[player.userID] += amount;
                return false;
            }
            var obj = player.GetComponent<WPlayer>();
            if (obj == null) {
                return false;
            }
            return obj.AddExp(amount, mess, targetId);
        }
        private float GetExp(BasePlayer player) {
            if (CheckEngine) {
                if (!CheckData.ContainsKey(player.userID)) return 0f;
                var info = CheckData[player.userID];
                float left = info - Mathf.FloorToInt(info);
                return left < 0 ? 0f : left;
            }
            if (!Base.ContainsKey(player)) return 0f;
            var infos = Base[player];
            float lefts = infos.Exp - Mathf.FloorToInt(infos.Exp);
            return lefts < 0 ? 0f : lefts;
        }
        private float GetCurrentExp(BasePlayer player) {
            if (CheckEngine) {
                if (!CheckData.ContainsKey(player.userID)) return 0f;
                var info = CheckData[player.userID];
                float left = info - Mathf.FloorToInt(info);
                return left < 0 ? 0f : left;
            }
            if (!Base.ContainsKey(player)) return 0f;
            var infos = Base[player];
            return infos.Exp;
        }
        /// <summary>
        /// Сохраняет логи и выводит ошибку если включён DEBUG
        /// </summary>
        private static void LogError(string text) {
            //_.PrintError(text);
            if (Settings.DebugErrors) _.LogToFile(_.Name, text, _);
        }
        /// <summary>
        /// Обновляет текущий счётчик EXP по середине экрана
        /// </summary>
        /// <param name="action">Тип, если стоит plus/minus - происходит анимация изменения</param>
        private static void UpdateExpCounter(BasePlayer player, ExpAction action, float newValue) {
            CuiElementContainer container = new CuiElementContainer();
            CuiHelper.DestroyUi(player, InitialLayer + ".EXP");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = $"20 -100", OffsetMax = $"-0 -15"
                }
                , Text = {
                    Text = $"<b>{newValue}</b><color=#865f5a>EXP</color>", Align = TextAnchor.UpperLeft, Font = "robotocondensed-regular.ttf", FontSize = 32, Color = "0.93 0.89 0.85 1"
                }
            }
            , InitialLayer + ".C", InitialLayer + ".EXP");
            if (action != ExpAction.None) {
                CuiHelper.DestroyUi(player, InitialLayer + ".EXP.Animation");
                container.Add(new CuiLabel {
                    FadeOut = 2f, RectTransform = {
                        AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = $"5 -100", OffsetMax = $"-0 -20"
                    }
                    , Text = {
                        Text = action == ExpAction.Plus ? "⇡" : "⇣", Align = TextAnchor.UpperLeft, Font = "robotocondensed-bold.ttf", FontSize = 28, Color = action == ExpAction.Plus ? "0.462 0.79 0.27" : "0.95 0.278 0.231"
                    }
                }
                , InitialLayer + ".C", InitialLayer + ".EXP.Animation");
            }
            CuiHelper.AddUi(player, container);
            if (action != ExpAction.None) CuiHelper.DestroyUi(player, InitialLayer + ".EXP.Animation");
        }
        private void LoadImages() {
            ImageLibrary.Call("AddImage", "https://i.imgur.com/YkC5Np4.png", "Custom_Locker_Image_Murder");
            ImageLibrary.Call("AddImage", "https://i.imgur.com/BQx3bap.png", "Custom_WhiteLocker_Image_Murder");
            ImageLibrary.Call("AddImage", "http://static.moscow.ovh/images/games/rust/icons/blueprintbase.png", "Custom_Blueprint");
            FetchImages();
        }
        private void FetchImages() {
            if (!((bool) ImageLibrary.Call("HasImage", "Custom_Locker_Image_Murder"))) {
                PrintError("C#> Images loaded failed [ERR]");
                timer.Once(1f, FetchImages);
                return;
            }
            if (!((bool) ImageLibrary.Call("HasImage", "Custom_Blueprint"))) {
                PrintError("C#> Images loaded failed [ERR]");
                timer.Once(1f, FetchImages);
                return;
            }
            BlueprintImage = (string) ImageLibrary.Call("GetImage", "Custom_Blueprint");
            LockerImage = (string) ImageLibrary.Call("GetImage", "Custom_Locker_Image_Murder");
         
// ... [Code preview truncated due to length. Full source in attached file] ...

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