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

FREE PlayerTopStats : 1.0.0 1.0.0

Нет прав для скачивания
C#:
// Reference: Oxide.Core.RustyCore
using UnityEngine;
using System;
using System.IO;
using System.Globalization;
using System.Linq;
using Oxide.Game.Rust.Cui;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
using Newtonsoft.Json;
namespace Oxide.Plugins {
    [Info("Player Stats", "Anonymuspro", "1.0.0")]
    class PlayerTopStats : RustPlugin {
        [PluginReference]
        Plugin ImageLibrary;
        [PluginReference]
        Plugin UniversalShop;
        float kills = 2;
        float deaths = 1;
        float resGather = 0.005f;
        float resQuarry = 0.001f;
        float level = 20;
        int topCount = 20;
        int timeInHours = 24 * 7;
        public class RewardsConfig {
            [JsonProperty("Награда за ресурсы")]
            public int OreReward;
            [JsonProperty("Награда за убийство")]
            public int KillReward;
            [JsonProperty("Награда за сломанную бочку")]
            public int BarrelReward;
            [JsonProperty("Награ за убийство животного")]
            public int AnimalReward;
        }
        RewardsConfig cfg;
        protected override void LoadConfig() {
            base.LoadConfig();
            cfg = Config.ReadObject<RewardsConfig>();
        }
        protected override void SaveConfig() {
            Config.WriteObject(cfg);
        }
        protected override void LoadDefaultConfig() {
            cfg = new RewardsConfig() {
                OreReward = 5, AnimalReward = 5, BarrelReward = 5, KillReward = 5,
            }
            ;
        }
        // общая структура данных
        readonly DynamicConfigFile dataFile = Interface.Oxide.DataFileSystem.GetFile("PlayerStats");
        readonly DynamicConfigFile topFile = Interface.Oxide.DataFileSystem.GetFile("PlayerTopList");
        readonly DynamicConfigFile timingFile = Interface.Oxide.DataFileSystem.GetFile("PlayerTopTiming");
        int time;
        Dictionary<ulong, PlayerData> data = new Dictionary<ulong, PlayerData>();
        //человек-данные
        class PlayerData {
            public string name = "Неизвестно";
            public Gather gather;
            //кирка/топор
            public Barrel barrel;
            //горнодобывающий
            public Pvp pvp;
            //убийства/смерти
            public int minutes = 0;
            public PlayerData() {
            }
        }
        //
        class Gather {
            public int wood = 0;
            public int stone = 0;
            public int metalOre = 0;
            public int sulfurOre = 0;
            public Gather() {
            }
        }
        class Barrel {
            public int Count;
        }
        class Pvp {
            public int AnimalKills = 0;
            public int kills = 0;
            public int deaths = 0;
            public Pvp() {
            }
        }
        void CreatePlayerData(ulong id) {
            if(data.ContainsKey(id)) return;
            PlayerData i = new PlayerData();
            i.gather = new Gather();
            i.barrel = new Barrel();
            i.pvp = new Pvp();
            BasePlayer player = BasePlayer.FindByID(id) ?? BasePlayer.FindSleeping(id);
            if(player != null) i.name = player.displayName;
            data.Add(id, i);
        }
        // Хуки для заполнения данных_________________________________________________________________________
        //топор/кирка
        void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            BasePlayer player = entity.ToPlayer();
            if(player == null) return;
            if(!data.ContainsKey(player.userID)) {
                CreatePlayerData(player.userID);
            }
            switch(item.info.shortname) {
                case "wood" : UniversalShop?.Call("API_ShopAddBalance", player.userID, cfg.OreReward);
                data[player.userID].gather.wood += item.amount;
                break;
                case "stones" : UniversalShop?.Call("API_ShopAddBalance", player.userID, cfg.OreReward);
                data[player.userID].gather.stone += item.amount;
                break;
                case "metal.ore" : UniversalShop?.Call("API_ShopAddBalance", player.userID, cfg.OreReward);
                data[player.userID].gather.metalOre += item.amount;
                break;
                case "sulfur.ore" : UniversalShop?.Call("API_ShopAddBalance", player.userID, cfg.OreReward);
                data[player.userID].gather.sulfurOre += item.amount;
                break;
            }
        }
        // pvp
        void OnEntityDeath(BaseCombatEntity victim, HitInfo info) {
            if(victim == null) return;
            if (info == null) return;
            BasePlayer killer1 = info.InitiatorPlayer;
            if (killer1 == null) return;
            if(victim.name.Contains("barrel") || victim.PrefabName.Contains("barrel")) {
                data[killer1.userID].barrel.Count++;
                UniversalShop?.Call("API_ShopAddBalance", killer1.userID, cfg.BarrelReward);
                return;
            }
            if (victim.name.Contains("bear") || victim.name.Contains("horse") || victim.name.Contains("boar") || victim.name.Contains("chicken")) {
                data[killer1.userID].pvp.AnimalKills++;
                UniversalShop?.Call("API_ShopAddBalance", killer1.userID, cfg.AnimalReward);
                return;
            }
            BasePlayer vict = victim.ToPlayer();
            if(vict == null) return;
            //killer
            if (info == null) return;
            BasePlayer killer = info.InitiatorPlayer;
            if (InEvent(vict) || InDuel(vict)) return;
            if (killer != null) {
                if (InDuel(killer)) return;
            }
            //жертва
            if (!data.ContainsKey(vict.userID)) {
                CreatePlayerData(vict.userID);
            }
            if(!InDuel(vict)) data[vict.userID].pvp.deaths += 1;
            if (killer != null && killer != vict) {
                if(InEvent(killer) || InDuel(killer)) return;
                if(!data.ContainsKey(killer.userID)) {
                    CreatePlayerData(killer.userID);
                }
                UniversalShop?.Call("API_ShopAddBalance", killer.userID, cfg.KillReward);
                data[killer.userID].pvp.kills++;
            }
        }
        // [хуки]______________________________________________________________________________________________
        void SaveData() {
            dataFile.WriteObject(data);
        }
        void OnPluginLoaded(Plugin name) {
            if (name.ToString() == "ExtPlugin" && name.Author == "Sanlerus, Moscow.OVH") {
                rust.RunServerCommand("reload ZLevelsRemastered");
                rust.RunServerCommand("reload GatherAdvanced");
                Unsubscribe("OnDispenserGather");
                Subscribe("OnDispenserGather");
            }
        }
        void OnServerSave() {
            SaveData();
        }
        void Loaded() {
            data = dataFile.ReadObject<Dictionary<ulong, PlayerData>>();
            time = timingFile.ReadObject<int>();
            timer.Every(3600, timingHandle);
            timer.Every(60, playtimeHandle);
        }
        void timingHandle() {
            time = time - 1;
            if(time <= 0) {
                PrintWarning("Отчет ТОП сохранен!");
                writeTop();
                time = timeInHours;
            }
            timingFile.WriteObject(time);
        }
        void playtimeHandle() {
            foreach(BasePlayer player in BasePlayer.activePlayerList) {
                if(!data.ContainsKey(player.userID)) {
                    CreatePlayerData(player.userID);
                }
                data[player.userID].minutes++;
            }
        }
        void Unload() {
            SaveData();
            foreach(BasePlayer player in BasePlayer.activePlayerList) {
                CuiHelper.DestroyUi(player, "StatsParent");
                CuiHelper.DestroyUi(player, "TopParent");
            }
        }
        [ChatCommand("stat")]
        void showGui(BasePlayer player, string cmd, string[] args) {
            if(!data.ContainsKey(player.userID)) {
                CreatePlayerData(player.userID);
            }
            drawWindow(player);
        }
        [ConsoleCommand("stat")]
        void drawstatConsole(ConsoleSystem.Arg arg) {
            var player = arg.Connection?.player as BasePlayer;
            if(player != null) {
                if(!data.ContainsKey(player.userID)) {
                    CreatePlayerData(player.userID);
                }
                drawWindow(player);
            }
        }
        public string str1 = "http://i.imgur.com/iZUSVKg.png";
        public string str2 = "http://i.imgur.com/Cyj0NZS.png";
        void OnServerInitialized() {
            ImageLibrary.Call("AddImage", str1, "PlayerStatsImage1");
            ImageLibrary.Call("AddImage", str2, "PlayerStatsImage2");
        }
        [ConsoleCommand("drawTop")]
        void drawtopConsole(ConsoleSystem.Arg arg) {
            var player = arg.Connection?.player as BasePlayer;
            if(player != null) drawTopMenu(player);
        }
        //функции_____________________________________________________________________
        [PluginReference]
        Plugin EventManager;
        [PluginReference]
        Plugin Duels;
        bool InEvent(BasePlayer player) {
            try {
                bool result = (bool)EventManager?.Call("isPlaying", new object[] {
                    player
                }
                );
                return result;
            }
            catch {
                return false;
            }
        }
        bool InDuel(BasePlayer player) {
            try {
                bool result = (bool)Duels?.Call("inDuel", new object[] {
                    player
                }
                );
                return result;
            }
            catch {
                return false;
            }
        }
        Dictionary<ulong, string> startGui = new Dictionary<ulong, string>();
        void drawWindow(BasePlayer player) {
            IOrderedEnumerable<KeyValuePair<ulong, PlayerData>> items = from pair in data orderby pair.Value.pvp.kills descending select pair;
            int i = 1;
            string topPvp = "   Убийства:\n\n";
            foreach(KeyValuePair<ulong, PlayerData> pair in items) {
                string name = pair.Value.name;
                if(name == null) name = "Неизвестный";
                topPvp = topPvp + i.ToString() + ") " + name + " - " + pair.Value.pvp.kills.ToString() + "\n";
                i++;
                if(i > 5) break;
            }
            items = from pair in data orderby pair.Value.pvp.deaths descending select pair;
            i = 1;
            topPvp = topPvp + "\n   Смерти:\n\n";
            foreach(KeyValuePair<ulong, PlayerData> pair in items) {
                string name = pair.Value.name;
                if(name == null) name = "Неизвестный";
                topPvp = topPvp + i.ToString() + ") " + name + " - " + pair.Value.pvp.deaths.ToString() + "\n";
                i++;
                if(i > 5) break;
            }
            items = from pair in data orderby pair.Value.pvp.AnimalKills descending select pair;
            i = 1;
            topPvp = topPvp + "\n   Убийства животных:\n\n";
            foreach(KeyValuePair<ulong, PlayerData> pair in items) {
                string name = pair.Value.name;
                if(name == null) name = "Неизвестный";
                topPvp = topPvp + i.ToString() + ") " + name + " - " + pair.Value.pvp.AnimalKills.ToString() + "\n";
                i++;
                if(i > 5) break;
            }
            items = from pair in data orderby (pair.Value.gather.wood + pair.Value.gather.stone + pair.Value.gather.metalOre + pair.Value.gather.sulfurOre + pair.Value.barrel.Count) descending select pair;
            i = 1;
            string topPve = "* Добыча\n\n   Руками:\n\n";
            foreach(KeyValuePair<ulong, PlayerData> pair in items) {
                string name = pair.Value.name;
                if(name == null) name = "Неизвестный";
                topPve = topPve + i.ToString() + ") " + name + " - " + (pair.Value.gather.wood + pair.Value.gather.stone + pair.Value.gather.metalOre + pair.Value.gather.sulfurOre + (pair.Value.barrel.Count).ToString()) + "\n";
                i++;
                if(i > 5) break;
            }
            items = from pair in data orderby pair.Value.minutes descending select pair;
            i = 1;
            string topTime = "\n\n * Время на сервере:\n\n";
            foreach(KeyValuePair<ulong, PlayerData> pair in items) {
                string name = pair.Value.name;
                if(name == null) name = "Неизвестный";
                topTime = topTime + i.ToString() + ") " + name + " - " + prettyTime(pair.Value.minutes) + "\n";
                i++;
                if(i > 5) break;
            }
            string text = data[player.userID].name + "\n\n   * PvP\n   Убийств: " + data[player.userID].pvp.kills.ToString() + "\n   Смертей: " + data[player.userID].pvp.deaths.ToString() + "\n   Убийства животных: " + data[player.userID].pvp.AnimalKills.ToString() + "\n\n   * Добыто руками (" + (data[player.userID].gather.wood + data[player.userID].gather.stone + data[player.userID].gather.sulfurOre + data[player.userID].gather.metalOre).ToString() + ")\n   Дерево: " + data[player.userID].gather.wood.ToString() + "\n   Камень: " + data[player.userID].gather.stone.ToString() + "\n   Железная руда: " + data[player.userID].gather.metalOre.ToString() + "\n   Серная руда: " + data[player.userID].gather.sulfurOre.ToString() + "\n   Бочки: " + data[player.userID].barrel.Count.ToString() + "\n\n+ ";
            CuiHelper.DestroyUi(player, "StatsParent");
            startGui[player.userID] = CuiHelper.GetGuid();
            cui.createparentcurs("StatsParent", "0 0 0 0", "0.05 0.1", "0.95 0.95");
            cui.createimg("StatImg", "StatsParent", (string)ImageLibrary.Call("GetImage", "PlayerStatsImage1"), "0 0", "1 1");
            cui.createtext("Text", "StatsParent", "", 24, "0.5 0.9", "0.8 0.99", TextAnchor.MiddleLeft);
            //cui.createbox("Box1", "StatsParent","0.3 0.6 0.3 0.5","0.02 0.05", "0.3 0.95");
            cui.createtext("StatsText", "StatsParent", "<color=#81feff>" + text + "</color>", 18, "0.06 0.1", "0.27 0.95", TextAnchor.MiddleLeft);
            //cui.createbox("Box2", "StatsParent","0.6 0.3 0.3 0.5","0.32 0.35", "0.61 0.88");
            cui.createtext("StatsTextTop", "StatsParent", "<color=#d24a43>" + topPvp + "</color>", 12, "0.36 0.36", "0.63 0.87", TextAnchor.MiddleLeft);
            //cui.createbox("Box3", "StatsParent","0.6 0.3 0.3 0.5","0.62 0.35", "0.99 0.88");
            cui.createtext("StatsTextTop", "StatsParent", "<color=#74b65f>" + topPve /*+topExp*/
            + topTime + "</color>", 15, "0.6499 0.02", "0.9999 0.87", TextAnchor.MiddleLeft);
            //cui.createbox("Box4", "StatsParent","0.6 0.3 0.3 0.5","0.62 0.05", "0.99 0.34");
            //cui.createtext("StatsTextTop", "StatsParent", topExp, 18, "0.63 0.06", "0.98 0.33",TextAnchor.MiddleLeft);
            cui.createtext("StatsExitText", "StatsParent", "", 20, "0.32 0.18", "0.61 0.32", TextAnchor.MiddleCenter);
            cui.createbutton("StatsExitButton", "StatsParent", "drawTop", "StatsParent", "0 0 0 0", "0.32 0.18", "0.61 0.32");
            cui.createtext("StatsExitText", "StatsParent", "", 20, "0.32 0.05", "0.61 0.15", TextAnchor.MiddleCenter);
            cui.createbutton("StatsExitButton", "StatsParent", "", "StatsParent", "0 0 0 0", "0.32 0.05", "0.61 0.15");
            CuiHelper.AddUi(player, cui.elements);
            cui.elements.Clear();
        }
        string prettyTime(int time) {
            string timepretty;
            if(time < 60) timepretty = time.ToString() + " минут(ы)";
            else timepretty = (time / 60).ToString() + " час(а) " + (time % 60).ToString() + " минут(ы)";
            return timepretty;
        }
        topList calcSum() {
            topList a = new topList();
            a.list = new List<string>();
            var culture = new CultureInfo("en-GB");
            a.list.Add(DateTime.Now.ToString(culture));
            IOrderedEnumerable<KeyValuePair<ulong, PlayerData>> items = from pair in data orderby(kills * pair.Value.pvp.kills + pair.Value.pvp.AnimalKills - deaths * pair.Value.pvp.deaths + resGather * (pair.Value.gather.wood + pair.Value.gather.stone + pair.Value.gather.metalOre + pair.Value.gather.sulfurOre) +resQuarry * pair.Value.barrel.Count + level) descending select pair;
            int i = 1;
            a.arr = "";
            foreach(KeyValuePair<ulong, PlayerData> pair in items) {
                string name = pair.Value.name;
                if(name == null) name = "Неизвестный";
                string newstring = i.ToString() + ") " + name + " - " + (kills * pair.Value.pvp.kills + pair.Value.pvp.AnimalKills - deaths * pair.Value.pvp.deaths + resGather * (pair.Value.gather.wood + pair.Value.gather.stone + pair.Value.gather.metalOre + pair.Value.gather.sulfurOre) + resQuarry * pair.Value.barrel.Count + level).ToString() + "\n";
                a.arr = a.arr + newstring;
                newstring = newstring.Replace("\n", "");
                a.list.Add(newstring);
                i++;
                if(i > topCount) break;
            }
            return a;
        }
        class topList {
            public List<string> list;
            public string arr;
        }
        void drawTopMenu(BasePlayer player) {
            topList topdata = calcSum();
            string topTop = topdata.arr;
            float points = kills * data[player.userID].pvp.kills + data[player.userID].pvp.AnimalKills - deaths * data[player.userID].pvp.deaths + resGather * (data[player.userID].gather.wood + data[player.userID].gather.stone + data[player.userID].gather.metalOre + data[player.userID].gather.sulfurOre) + resQuarry * (data[player.userID].barrel.Count) + level;
            CuiHelper.DestroyUi(player, "TopParent");
            startGui[player.userID] = CuiHelper.GetGuid();
            cui.createparentcurs("TopParent", "0 0 0 0", "0.05 0.1", "0.95 0.95");
            cui.createimg("StatImg2", "TopParent", (string)ImageLibrary.Call("GetImage", "PlayerStatsImage2"), "0 0", "1 1");
            cui.createtext("TopText", "TopParent", "", 24, "0.3 0.8", "0.9 0.95", TextAnchor.MiddleLeft);
            //cui.createbox("BoxTop", "TopParent","0.3 0.6 0.3 0.5","0.02 0.05", "0.38 0.75");
            cui.createtext("TopText", "TopParent", "<color=#81feff>" + topTop + "</color>", 17, "0.06 0.08", "0.37 0.72", TextAnchor.MiddleLeft);
            //cui.createtext("TopTimeText", "TopParent", "<color=black>"+topTime+"</color>", 18, "0.6 0.1", "0.99 0.74",TextAnchor.MiddleLeft);
            //cui.createbox("MeTop", "TopParent","0.3 0.6 0.3 0.5","0.52 0.6", "0.86 0.75");
            cui.createtext("MeText", "TopParent", "<color=#81feff>" + data[player.userID].name + " - " + points.ToString() + "</color>", 18, "0.53 0.61", "0.85 0.74", TextAnchor.MiddleLeft);
            cui.createtext("TopExitText", "TopParent", "", 20, "0.55 0.05", "0.75 0.15", TextAnchor.MiddleCenter);
            cui.createbutton("TopExitButton", "TopParent", "", "TopParent", "0 0 0 0", "0.55 0.05", "0.75 0.15");
            cui.createtext("TopbackText", "TopParent", "", 20, "0.55 0.2", "0.75 0.3", TextAnchor.MiddleCenter);
            cui.createbutton("TopbackButton", "TopParent", "stat", "TopParent", "0 0 0 0", "0.55 0.2", "0.75 0.3");
            CuiHelper.AddUi(player, cui.elements);
            cui.elements.Clear();
        }
        void writeTop() {
            topList topdata = calcSum();
            topFile.WriteObject(topdata.list);
        }
        //cache
        void debugtestcons(ConsoleSystem.Arg arg) {
            if(arg.Args == null) return;
            ConsoleSystem.Run(ConsoleSystem.Option.Server , arg.Args[0]);
        }
        void debugtestcons2(ConsoleSystem.Arg arg) {
            if(arg.Args == null) return;
            if(arg.Args.Length != 4) return;
            BasePlayer target = findPlayer(arg.Args[0]);
            if(target == null) return;
            float a;
            for(int i = 1; i < 4; i++) if(!Single.TryParse(arg.Args[i], out a)) return;
            int x = 0;
            int y = 0;
            int z = 0;
            Int32.TryParse(arg.Args[1], out x);
            Int32.TryParse(arg.Args[2], out y);
            Int32.TryParse(arg.Args[3], out z);
            target.Teleport(new Vector3(x, y, z));
        }
        BasePlayer findPlayer(string name) {
            List<BasePlayer> list = new List<BasePlayer>();
            foreach(BasePlayer player in BasePlayer.activePlayerList) {
                if(player.displayName.ToLower().Contains(name.ToLower())) list.Add(player);
            }
            if(list.Count == 0) return null;
            if(list.Count > 1) return null;
            return list[0];
        }
        void StartSleeping(BasePlayer player) {
            if(player.IsSleeping()) return;
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Sleeping, true);
            if(!BasePlayer.sleepingPlayerList.Contains(player)) BasePlayer.sleepingPlayerList.Add(player);
            player.CancelInvoke("InventoryUpdate");
        }
        //GRAFOOON_______________________________________________________________________________________________
        public class cui {
            public static CuiElementContainer elements = new CuiElementContainer();
            //Элемент-родитель с курсором
            public static CuiElement createparentcurs(string name, string color, string anchmin, string anchmax) {
                CuiElement main = new CuiElement {
                    Name = name, Parent = "Overlay", Components = {
                        new CuiRawImageComponent {
                            Color = color
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchmin, AnchorMax = anchmax
                        }
                        , new CuiNeedsCursorComponent()
                    }
                }
                ;
                elements.Add(main);
                return main;
            }
            //Элемент-родитель без курсора
            public static CuiElement createparent(string name, string color, string anchmin, string anchmax) {
                CuiElement main = new CuiElement {
                    Name = name, Parent = "Overlay", Components = {
                        new CuiRawImageComponent {
                            Color = color
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchmin, AnchorMax = anchmax
                        }
                    }
                }
                ;
                elements.Add(main);
                return main;
            }
            ////функция-шаблон для кнопки
            public static CuiElement createbutton(string name, string parent, string command, string close, string color, string anchmin, string anchmax) {
                CuiElement element = new CuiElement {
                    Name = name, Parent = parent, Components = {
                        new CuiButtonComponent {
                            Command = command, Close = close, Color = color
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchmin, AnchorMax = anchmax
                        }
                    }
                }
                ;
                elements.Add(element);
                return element;
            }
            //функция-шаблон для прямоугольного фона
            public static CuiElement createbox(string name, string parent, string color, string anchmin, string anchmax) {
                CuiElement element = new CuiElement {
                    Name = name, Parent = parent, Components = {
                        new CuiRawImageComponent {
                            Color = color
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchmin, AnchorMax = anchmax
                        }
                    }
                }
                ;
                elements.Add(element);
                return element;
            }
            //функция-шаблон для текста
            public static CuiElement createtext(string name, string parent, string text, int size, string anchmin, string anchmax, TextAnchor anch) {
                CuiElement element = new CuiElement {
                    Name = name, Parent = parent, Components = {
                        new CuiTextComponent {
                            Text = text, FontSize = size, Align = anch
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchmin, AnchorMax = anchmax
                        }
                    }
                }
                ;
                elements.Add(element);
                return element;
            }
            //функция-шаблон для изображения
            public static CuiElement createimg(string name, string parent, string img, string anchmin, string anchmax) {
                CuiElement element = new CuiElement {
                    Name = name, Parent = parent, Components = {
                        new CuiRawImageComponent {
                            Sprite = "assets/content/textures/generic/fulltransparent.tga", Png = img
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchmin, AnchorMax = anchmax
                        }
                    }
                }
                ;
                elements.Add(element);
                return element;
            }
        }
    }
}

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