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

FREE BetterStatistics : 1.0.14 1.0.14

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Database;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
///Скачано с дискорд сервера Rust Edit [PRO+]
///discord.gg/9vyTXsJyKR
namespace Oxide.Plugins {
    [Info("Better Statistics", "discord.gg/9vyTXsJyKR", "1.0.14")]
    [Description("A plugin that syncs players statistics to a MySQL database.")]
    public class BetterStatistics : CovalencePlugin {
#region Config
        static Configuration config;
        public class DBInfo {
            [JsonProperty(PropertyName = "Host IP")]
            public string sql_host;
            [JsonProperty(PropertyName = "Port")]
            public int sql_port;
            [JsonProperty(PropertyName = "Database name")]
            public string sql_db;
            [JsonProperty(PropertyName = "Username")]
            public string sql_user;
            [JsonProperty(PropertyName = "Password")]
            public string sql_passwword;
        }
        public class Configuration {
            [JsonProperty(PropertyName = "Developer Mode (Debug Messages)")]
            public bool developerMode;
            [JsonProperty(PropertyName = "MySQL Database Connection Info")]
            public DBInfo connectionInfo;
            [JsonProperty(PropertyName = "Server Prefix (For tables Ex: (prefix)_stats_wipe, (prefix)_stats_overall)")]
            public string serverPrefix;
            [JsonProperty(PropertyName = "Save Interval (Mins) (0 = Disabled)")]
            public int saveInterval;
            [JsonProperty(PropertyName = "Use In-Game UI")]
            public bool useIngameUI;
            [JsonProperty(PropertyName = "Exclude NPC Type Deaths from death count?")]
            public bool excludeNPCDeaths;
            [JsonProperty(PropertyName = "Only count kills on players that have a stash on them?")]
            public bool onlyStashKills;
            public static Configuration DefaultConfig() {
                return new Configuration {
                    developerMode = false, connectionInfo = new DBInfo {
                        sql_host = "localhost", sql_port = 3306, sql_user = "root", sql_passwword = "", sql_db = "betterstatistics"
                    }
                    , serverPrefix = "main", saveInterval = 10, useIngameUI = true, excludeNPCDeaths = true, onlyStashKills = false
                }
                ;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
                SaveConfig();
            }
            catch (Exception e) {
                Debug.LogException(e);
                PrintWarning("Creating new config file.");
                LoadDefaultConfig();
            }
        }
        protected override void LoadDefaultConfig() => config = Configuration.DefaultConfig();
        protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Language
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["UpdatedPlayerStats"]
                = "Updated {0} stats.", ["NoDatabaseConnection"] = "Database connection failed.Please check your credentials and try again.", ["PlayerNotFound"] = "Player not found in wipe stats table.", ["PlayerNotFoundOverall"] = "Player not found in overall stats table, these stats are filled when the server wipes.", ["UITitle"] = "Better Statistics", ["UIWipeButton"] = "WIPE", ["UIOverallButton"] = "OVERALL", ["UIExitButton"] = "EXIT", ["UIHead"] = "Head", ["UITorso"] = "Torso", ["UILeftArm"] = "Left Arm", ["UIRightArm"] = "Right Arm", ["UILeftLeg"] = "Left Leg", ["UIRightLeg"] = "Right Leg", ["UILeftFoot"] = "Left Foot", ["UIRightFoot"] = "Right Foot", ["UIPlayerStats"] = "Player Stats", ["UIConnects"] = "Connects", ["UIPlaytime"] = "Playtime", ["UIKills"] = "Kills", ["UIDeaths"] = "Deaths", ["UISuicides"] = "Suicides", ["UIWounded"] = "Wounded", ["UIKDRatio"] = "K/D Ratio", ["UIAccuracy"] = "Accuracy", ["UISatchels"] = "Satchels", ["UIC4"] = "C4", ["UIRockets"] = "Rockets", ["UITCsDestroyed"] = "TCs Destroyed", ["UINPCKills"] = "NPC Kills", ["UIChickens"] = "Chickens", ["UIBoars"] = "Boars", ["UIStags"] = "Stags", ["UIHorses"] = "Horses", ["UIWolves"] = "Wolves", ["UIBears"] = "Bears", ["UIScientists"] = "Scientists", ["UIHelicopters"] = "Helicopters", ["UIBradleys"] = "Bradleys", ["UIWeaponKills"] = "Weapon Kills", ["UINextPage"] = "NEXT PAGE", ["UIPreviousPage"] = "PREV PAGE"
            }
            , this);
        }
        private string GetLang(string langKey, params object[] args) {
            return string.Format(lang.GetMessage(langKey, this), args);
        }
#endregion
#region Classes
        public class PlayerStats {
            public string name = string.Empty;
            public int connections = 0;
            public int playtime = 0;
            public DateTime connected = DateTime.Now;
            public int kills = 0;
            public int deaths = 0;
            public int bfired = 0;
            public int suicides = 0;
            public int wounded = 0;
            public int rocketsfired = 0;
            public int c4thrown = 0;
            public int satchelsthrown = 0;
            public int tcsdestroyed = 0;
            public NPCStats npcStats = new NPCStats();
            public WeaponStats weaponStats = new WeaponStats();
            public BodyParts hits = new BodyParts();
        }
        public class NPCStats {
            public int chickens = 0;
            public int boars = 0;
            public int deers = 0;
            public int horses = 0;
            public int wolves = 0;
            public int bears = 0;
            public int scientists = 0;
            public int helicopters = 0;
            public int bradleys = 0;
        }
        ;
        public class WeaponStats {
            public int ak47 = 0;
            public int lr300 = 0;
            public int m39 = 0;
            public int sar = 0;
            public int hmlmg = 0;
            public int m249 = 0;
            public int bolt = 0;
            public int l96 = 0;
            public int mp5 = 0;
            public int thompson = 0;
            public int custom = 0;
            public int doublebarrel = 0;
            public int pump = 0;
            public int spaz12 = 0;
            public int m92 = 0;
            public int python = 0;
            public int semipistol = 0;
            public int revolver = 0;
            public int waterpipe = 0;
            public int eoka = 0;
            public int compound = 0;
            public int crossbow = 0;
            public int bow = 0;
        }
        ;
        public class BodyParts {
            public int head = 0;
            public int torso = 0;
            public int lefthand = 0;
            public int righthand = 0;
            public int leftleg = 0;
            public int rightleg = 0;
            public int leftfoot = 0;
            public int rightfoot = 0;
        }
        ;
        public class Weapon {
            public string WeaponName = "";
            public string WeaponIcon = "";
        }
        List<Weapon> weapons = new List<Weapon>() {
            new Weapon {
                WeaponName = "AK", WeaponIcon = "https://i.imgur.com/DX6M8IM.png"
            }
            , new Weapon {
                WeaponName = "LR", WeaponIcon = "https://i.imgur.com/EqSj6od.png"
            }
            , new Weapon {
                WeaponName = "M39", WeaponIcon = "https://i.imgur.com/pj5eK7W.png"
            }
            , new Weapon {
                WeaponName = "M249", WeaponIcon = "https://i.imgur.com/5ebpq7S.png"
            }
            , new Weapon {
                WeaponName = "HMLMG", WeaponIcon = "https://i.imgur.com/WcruPRb.png"
            }
            , new Weapon {
                WeaponName = "SAR", WeaponIcon = "https://i.imgur.com/n1N0y5R.png"
            }
            , new Weapon {
                WeaponName = "L9", WeaponIcon = "https://i.imgur.com/WG8tWwT.png"
            }
            , new Weapon {
                WeaponName = "BOLT", WeaponIcon = "https://i.imgur.com/SC8tLG6.png"
            }
            , new Weapon {
                WeaponName = "MP5", WeaponIcon = "https://i.imgur.com/trJCQry.png"
            }
            , new Weapon {
                WeaponName = "THOMPSON", WeaponIcon = "https://i.imgur.com/J4cAEf8.png"
            }
            , new Weapon {
                WeaponName = "CUSTOMSMG", WeaponIcon = "https://i.imgur.com/KqK3ffK.png"
            }
            , new Weapon {
                WeaponName = "PUMP", WeaponIcon = "https://i.imgur.com/7LwdMsG.png"
            }
            , new Weapon {
                WeaponName = "DOUBLE", WeaponIcon = "https://i.imgur.com/eXT2fkS.png"
            }
            , new Weapon {
                WeaponName = "SPAZ12", WeaponIcon = "https://i.imgur.com/PKfrRmz.png"
            }
            , new Weapon {
                WeaponName = "M92", WeaponIcon = "https://i.imgur.com/nLn1Kyx.png"
            }
            , new Weapon {
                WeaponName = "PYTHON", WeaponIcon = "https://i.imgur.com/BlJKetO.png"
            }
            , new Weapon {
                WeaponName = "SEMIPISTOL", WeaponIcon = "https://i.imgur.com/OCH6rsz.png"
            }
            , new Weapon {
                WeaponName = "REVOLVER", WeaponIcon = "https://i.imgur.com/NRlB8Ds.png"
            }
            , new Weapon {
                WeaponName = "WATERPIPE", WeaponIcon = "https://i.imgur.com/fHKeAhR.png"
            }
            , new Weapon {
                WeaponName = "EOKA", WeaponIcon = "https://i.imgur.com/Uh6bya5.png"
            }
            , new Weapon {
                WeaponName = "COMPOUND", WeaponIcon = "https://i.imgur.com/pU8CXpI.png"
            }
            , new Weapon {
                WeaponName = "CROSSBOW", WeaponIcon = "https://i.imgur.com/e6ukhQV.png"
            }
            , new Weapon {
                WeaponName = "BOW", WeaponIcon = "https://i.imgur.com/lfbpVqR.png"
            }
        }
        ;
        private int GetAmount(WeaponStats wStats, string weapon) {
            switch (weapon) {
                case "AK" : return wStats.ak47;
                case "LR" : return wStats.lr300;
                case "M39" : return wStats.m39;
                case "M249" : return wStats.m249;
                case "HMLMG" : return wStats.hmlmg;
                case "SAR" : return wStats.sar;
                case "L9" : return wStats.l96;
                case "BOLT" : return wStats.bolt;
                case "MP5" : return wStats.mp5;
                case "THOMPSON" : return wStats.thompson;
                case "CUSTOMSMG" : return wStats.custom;
                case "PUMP" : return wStats.pump;
                case "DOUBLE" : return wStats.doublebarrel;
                case "SPAZ12" : return wStats.spaz12;
                case "M92" : return wStats.m92;
                case "PYTHON" : return wStats.python;
                case "SEMIPISTOL" : return wStats.semipistol;
                case "REVOLVER" : return wStats.revolver;
                case "WATERPIPE" : return wStats.waterpipe;
                case "EOKA" : return wStats.eoka;
                case "COMPOUND" : return wStats.compound;
                case "CROSSBOW" : return wStats.crossbow;
                case "BOW" : return wStats.bow;
            }
            return -1;
        }
#endregion
#region Defines
        [PluginReference]
        private Plugin ImageLibrary;
        Dictionary<string, PlayerStats> playerStats = new Dictionary<string, PlayerStats>();
        Dictionary<string, PlayerStats> playerStatsOverall = new Dictionary<string, PlayerStats>();
        Core.MySql.Libraries.MySql SQL = Interface.Oxide.GetLibrary<Core.MySql.Libraries.MySql>();
        Connection connection;
        PlayerStats stats;
        private const string TableExists = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @0";
        BasePlayer HeliAttacker = null;
        DamageType[] suicideDamageTypes = {
            DamageType.Suicide, DamageType.Radiation, DamageType.RadiationExposure, DamageType.Poison, DamageType.Hunger, DamageType.Thirst, DamageType.Fall, DamageType.Drowned
        }
        ;
#endregion
#region Hooks
        void Loaded() {
            connection = SQL.OpenDb(config.connectionInfo.sql_host, config.connectionInfo.sql_port, config.connectionInfo.sql_db, config.connectionInfo.sql_user, config.connectionInfo.sql_passwword, this);
            connection.Con.Open();
            if (connection == null || connection.Con == null) {
                Puts(GetLang("NoDatabaseConnection"));
                return;
            }
        }
        void Unload() {
            connection?.Con?.Dispose();
            config = null;
        }
        void OnNewSave(string filename) {
            if (config.developerMode) Puts("Moving wipe table to overall due to new save file.");
            var query = Sql.Builder.Append($"CALL `wipeTime`('{config.serverPrefix}')");
            SQL.Query(query, connection, created => {
            }
            );
        }
        void OnServerSave() {
            if (ServerMgr.Instance.Restarting) {
                if (config.developerMode) Puts("Ran OnServerSave since server is restarting.");
                SaveAllStats();
            }
        }
        void OnServerInitialized(bool initial) {
            ServerMgr.Instance.StartCoroutine(Startup());
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/BtYyVsQ.png", "PlayerImage");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/hvnWown.png", "GrungeBackground");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/FZHGHUc.png", "ConnectionsIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/DRdUVK6.png", "PlaytimeIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/0Bmhgma.png", "DeathsIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/5Sbd7Ir.png", "KDRIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/85BOzMc.png", "AccuracyIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/ycz4eyv.png", "WoundedIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/ttLSDHS.png", "SuicidesIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/bZA0E92.png", "SatchelsIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/4ix2QDq.png", "C4Icon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/m0VKILI.png", "RocketsIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/n2b0FlG.png", "TCIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/iXPMAhu.png", "ChickenIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/suelqfc.png", "BoarIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/VIszPrw.png", "DeerIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/nErC1Ht.png", "HorseIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/LGka2Zw.png", "WolveIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/0lYoss1.png", "BearIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/09sY8jQ.png", "ScientistIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/q0KkIgi.png", "HelicopterIcon");
            ImageLibrary?.Call("AddImage", "https://i.imgur.com/RwqvbVv.png", "BradleyIcon");
            foreach (var weapon in weapons) ImageLibrary?.Call("AddImage", weapon.WeaponIcon, weapon.WeaponName);
            if (config.saveInterval != 0) timer.Every(config.saveInterval * 60, () => {
                SaveAllStats();
            }
            );
            if (!initial) {
                foreach (BasePlayer player in BasePlayer.activePlayerList) if (playerStats.TryGetValue(player.UserIDString, out stats)) stats.connected = DateTime.Now;
            }
        }
        void OnPlayerConnected(BasePlayer player) {
            if (connection == null || connection.Con == null) return;
            if (playerStats.TryGetValue(player.UserIDString, out stats)) {
                stats.connected = DateTime.Now;
                stats.connections += 1;
            }
            Sql query = Sql.Builder.Append($"SELECT steamid FROM {config.serverPrefix}_stats_wipe WHERE steamid = '{player.userID}'");
            SQL.Query(query, connection, list => {
                if (list.Count == 0) {
                    Sql insquery = Sql.Builder.Append($"INSERT INTO {config.serverPrefix}_stats_wipe (steamid, name) VALUES ({player.UserIDString}, '{RemoveSpecialCharacters(player.displayName)}')");
                    SQL.Insert(insquery, connection);
                    playerStats.Add(player.UserIDString, new PlayerStats {
                        name = RemoveSpecialCharacters(player.displayName), connections = 1, playtime = 0, kills = 0, deaths = 0, bfired = 0, suicides = 0, wounded = 0, c4thrown = 0, satchelsthrown = 0, rocketsfired = 0, tcsdestroyed = 0, npcStats = new NPCStats {
                            chickens = 0, boars = 0, deers = 0, horses = 0, wolves = 0, bears = 0, scientists = 0, helicopters = 0, bradleys = 0
                        }
                        , weaponStats = new WeaponStats {
                            ak47 = 0, lr300 = 0, m39 = 0, sar = 0, m249 = 0, hmlmg = 0, l96 = 0, bolt = 0, mp5 = 0, thompson = 0, custom = 0, pump = 0, doublebarrel = 0, spaz12 = 0, m92 = 0, python = 0, semipistol = 0, revolver = 0, waterpipe = 0, eoka = 0, compound = 0, crossbow = 0, bow = 0
                        }
                        , hits = new BodyParts {
                            head = 0, torso = 0, lefthand = 0, righthand = 0, leftleg = 0, rightleg = 0, leftfoot = 0, rightfoot = 0
                        }
                        ,
                    }
                    );
                }
            }
            );
        }
        void OnPlayerDisconnected(BasePlayer player, string reason) {
            if (reason.Equals("Server Restarting", StringComparison.OrdinalIgnoreCase)) return;
            SavePlayerStats(player, true);
        }
        void OnEntityDeath(BasePlayer player, HitInfo info) {
            if (!playerStats.TryGetValue(player.UserIDString, out stats)) return;
            if (suicideDamageTypes.Contains(player.lastDamage)) stats.suicides++;
            else {
                if (!(config.excludeNPCDeaths && info?.Initiator is BaseNpc)) stats.deaths++;
            }
            BasePlayer attacker = info?.InitiatorPlayer;
            if (attacker == null || attacker == player || (attacker.currentTeam > 0 && attacker.currentTeam == player.currentTeam) || (config.onlyStashKills && !player.HasPlayerFlag(BasePlayer.PlayerFlags.DisplaySash))) return;
            if (!playerStats.TryGetValue(attacker.UserIDString, out stats)) return;
            stats.kills++;
            Item weaponItem = info.Weapon?.GetItem();
            if (weaponItem == null) return;
            switch (weaponItem.info.shortname) {
                case "rifle.ak" : case "rifle.ak.ice" : stats.weaponStats.ak47++;
                break;
                case "rifle.lr300" : stats.weaponStats.lr300++;
                break;
                case "rifle.m39" : stats.weaponStats.m39++;
                break;
                case "rifle.semiauto" : stats.weaponStats.sar++;
                break;
                case "lmg.m249" : stats.weaponStats.m249++;
                break;
                case "hmlmg" : stats.weaponStats.hmlmg++;
                break;
                case "rifle.l96" : stats.weaponStats.l96++;
                break;
                case "rifle.bolt" : stats.weaponStats.bolt++;
                break;
                case "smg.mp5" : stats.weaponStats.mp5++;
                break;
                case "smg.thompson" : stats.weaponStats.thompson++;
                break;
                case "smg.2" : stats.weaponStats.custom++;
                break;
                case "shotgun.double" : stats.weaponStats.doublebarrel++;
                break;
                case "shotgun.pump" : stats.weaponStats.pump++;
                break;
                case "shotgun.spas12" : stats.weaponStats.spaz12++;
                break;
                case "pistol.m92" : stats.weaponStats.m92++;
                break;
                case "pistol.python" : stats.weaponStats.python++;
                break;
                case "pistol.semiauto" : stats.weaponStats.semipistol++;
                break;
                case "pistol.revolver" : stats.weaponStats.revolver++;
                break;
                case "shotgun.waterpipe" : stats.weaponStats.waterpipe++;
                break;
                case "pistol.eoka" : stats.weaponStats.eoka++;
                break;
                case "bow.compound" : stats.weaponStats.compound++;
                break;
                case "crossbow" : stats.weaponStats.crossbow++;
                break;
                case "bow.hunting" : stats.weaponStats.bow++;
                break;
            }
        }
        void OnEntityDeath(BuildingPrivlidge entity, HitInfo info) {
            BasePlayer attacker = info?.InitiatorPlayer;
            if (attacker == null) return;
            if (playerStats.TryGetValue(attacker.UserIDString, out stats)) stats.tcsdestroyed++;
        }
        void OnEntityDeath(NPCPlayer scientist, HitInfo info) {
            BasePlayer attacker = info?.InitiatorPlayer;
            if (attacker == null) return;
            if (playerStats.TryGetValue(attacker.UserIDString, out stats)) stats.npcStats.scientists++;
        }
        void OnEntityDeath(BaseAnimalNPC animal, HitInfo info) {
            BasePlayer attacker = info?.InitiatorPlayer;
            if (attacker == null) return;
            if (playerStats.TryGetValue(attacker.UserIDString, out stats)) {
                switch (animal.ShortPrefabName) {
                    case "chicken" : stats.npcStats.chickens++;
                    break;
                    case "boar" : stats.npcStats.boars++;
                    break;
                    case "stag" : stats.npcStats.deers++;
                    break;
                    case "horse" : stats.npcStats.horses++;
                    break;
                    case "wolf" : stats.npcStats.wolves++;
                    break;
                    case "bear" : stats.npcStats.bears++;
                    break;
                }
            }
        }
        void OnEntityTakeDamage(BaseHelicopter entity, HitInfo info) {
            if (info.Initiator is BasePlayer) HeliAttacker = info?.InitiatorPlayer;
        }
        void OnEntityDeath(BaseHelicopter heli, HitInfo info) {
            if (HeliAttacker == null) return;
            if (playerStats.TryGetValue(HeliAttacker.UserIDString, out stats)) stats.npcStats.helicopters++;
            HeliAttacker = null;
        }
        void OnEntityDeath(BradleyAPC bradley, HitInfo info) {
            BasePlayer attacker = info?.InitiatorPlayer;
            if (attacker == null) return;
            if (playerStats.TryGetValue(attacker.UserIDString, out stats)) stats.npcStats.bradleys++;
        }
        void OnExplosiveThrown(BasePlayer player, BaseEntity entity) {
            if (!playerStats.TryGetValue(player.UserIDString, out stats)) return;
            switch (player.GetActiveItem()?.info.shortname) {
                case "explosive.timed" : stats.c4thrown++;
                break;
                case "explosive.satchel" : stats.satchelsthrown++;
                break;
            }
        }
        void OnRocketLaunched(BasePlayer player, BaseEntity entity) {
            if (!playerStats.TryGetValue(player.UserIDString, out stats)) return;
            stats.rocketsfired++;
        }
        object OnPlayerWound(BasePlayer player, HitInfo hitInfo) {
            if (playerStats.TryGetValue(player.UserIDString, out stats)) stats.wounded++;
            return null;
        }
        object OnPlayerAttack(BasePlayer attacker, HitInfo info) {
            BasePlayer victim = info.HitEntity?.ToPlayer();
            if (victim != null) {
                if (!playerStats.TryGetValue(attacker.UserIDString, out stats)) return null;
                switch (info.boneName.ToLower()) {
                    case "head" : stats.hits.head++;
                    break;
                    case "neck" : case "chest" : case "lowerspine" : stats.hits.torso++;
                    break;
                    case "pelvis" : case "hip" : stats.hits.leftleg++;
                    stats.hits.rightleg++;
                    break;
                    case "left knee" : stats.hits.leftleg++;
                    break;
                    case "right knee" : stats.hits.rightleg++;
                    break;
                    case "left foot" : stats.hits.leftfoot++;
                    break;
                    case "right foot" : stats.hits.rightfoot++;
                    break;
                    case "left arm" : case "left forearm" : case "left hand" : stats.hits.lefthand++;
                    break;
                    case "right arm" : case "right forearm" : case "right hand" : stats.hits.righthand++;
                    break;
                }
            }
            return null;
        }
        void OnWeaponFired(BaseProjectile projectile, BasePlayer player, ItemModProjectile mod, ProtoBuf.ProjectileShoot projectiles) {
            if (!playerStats.TryGetValue(player.UserIDString, out stats)) return;
            stats.bfired++;
        }
#endregion
#region Functions
        public string RemoveSpecialCharacters(string str) {
            return str.Replace("'", "");
        }
        string CalculateAccuracy(int bulletsFired, BodyParts hits) {
            int totalHits = hits.head + hits.torso + hits.lefthand + hits.righthand + hits.leftleg + hits.rightleg + hits.leftfoot + hits.rightfoot;
            if (totalHits == 0 || bulletsFired == 0) return "100%";
            return $"{Math.Round(((float)totalHits / bulletsFired) * 100, 2)}%";
        }
        void CreateTable(string tableName) {
            Sql query = Sql.Builder.Append(TableExists, tableName);
            SQL.Query(query, connection, list => {
                if (list.Count == 0) {
                    var queryNew = Sql.Builder.Append($"CALL `createTable`('{tableName}')");
                    SQL.Query(queryNew, connection, created => {
                    }
                    );
                }
            }
            );
        }
        void SaveAllStats() {
            foreach (BasePlayer player in BasePlayer.activePlayerList) SavePlayerStats(player);
        }
        void SavePlayerStats(BasePlayer player, bool disconnect = false) {
            if (connection == null || connection.Con == null) return;
            if (player == null) return;
            if (playerStats.TryGetValue(player.UserIDString, out stats)) {
                stats.playtime += (int)DateTime.Now.Subtract(stats.connected).TotalMinutes;
                stats.connected = DateTime.Now;
                var query = Sql.Builder.Append($"UPDATE {config.serverPrefix}_stats_wipe SET name = '{RemoveSpecialCharacters(player.displayName)}', connections = {stats.connections}, playtime = {stats.playtime}, kills = {stats.kills}, deaths = {stats.deaths}, bfired = {stats.bfired}, suicides = {stats.suicides}, wounded = {stats.wounded}, c4thrown = {stats.c4thrown}, satchelsthrown = {stats.satchelsthrown}, rocketsfired = {stats.rocketsfired}, tcsdestroyed = {stats.tcsdestroyed}, chickens = {stats.npcStats.chickens}, boars = {stats.npcStats.boars}, deers = {stats.npcStats.deers}, horses = {stats.npcStats.horses}, wolves = {stats.npcStats.wolves}, bears = {stats.npcStats.bears}, scientists = {stats.npcStats.scientists}, helicopters = {stats.npcStats.helicopters}, bradleys = {stats.npcStats.bradleys}, ak47 = {stats.weaponStats.ak47}, lr300 = {stats.weaponStats.lr300}, m39 = {stats.weaponStats.m39}, sar = {stats.weaponStats.sar}, m249 = {stats.weaponStats.m249}, hmlmg = {stats.weaponStats.hmlmg}, l96 = {stats.weaponStats.l96}, bolt = {stats.weaponStats.bolt}, mp5 = {stats.weaponStats.mp5}, thompson = {stats.weaponStats.thompson}, custom = {stats.weaponStats.custom}, pump = {stats.weaponStats.pump}, doublebarrel = {stats.weaponStats.doublebarrel}, spaz12 = {stats.weaponStats.spaz12}, m92 = {stats.weaponStats.m92}, python = {stats.weaponStats.python}, semipistol = {stats.weaponStats.semipistol}, revolver = {stats.weaponStats.revolver}, waterpipe = {stats.weaponStats.waterpipe}, eoka = {stats.weaponStats.eoka}, compound = {stats.weaponStats.compound}, crossbow = {stats.weaponStats.crossbow}, bow = {stats.weaponStats.bow}, head_hits = {stats.hits.head}, torso_hits = {stats.hits.torso}, leftarm_hits = {stats.hits.lefthand}, rightarm_hits = {stats.hits.righthand}, leftleg_hits = {stats.hits.leftleg}, rightleg_hits = {stats.hits.rightleg}, leftfoot_hits = {stats.hits.leftfoot}, rightfoot_hits = {stats.hits.rightfoot} WHERE steamid = {player.UserIDString}");
                SQL.Update(query, connection, output => {
                    if (player == null) return;
                    if (config.developerMode) Puts(GetLang("UpdatedPlayerStats", RemoveSpecialCharacters(player.displayName)));
                }
                );
            }
        }
        IEnumerator Startup() {
            CreateTable($"{config.serverPrefix}_stats_wipe");
            CreateTable($"{config.serverPrefix}_stats_overall");
            yield return CoroutineEx.waitForSeconds(3f);
            Sql query = Sql.Builder.Append($"SELECT * FROM {config.serverPrefix}_stats_wipe");
            SQL.Query(query, connection, list => {
                playerStats.Clear();
                foreach (var stats in list) {
                    if (playerStats.ContainsKey(stats.Values.ElementAt(2).ToString())) continue;
                    playerStats.Add(stats.Values.ElementAt(2).ToString(), new PlayerStats {
                        name = stats.Values.ElementAt(1).ToString(), connections = Convert.ToInt32(stats.Values.ElementAt(3)), playtime = Convert.ToInt32(stats.Values.ElementAt(4)), kills = Convert.ToInt32(stats.Values.ElementAt(5)), deaths = Convert.ToInt32(stats.Values.ElementAt(6)), bfired = Convert.ToInt32(stats.Values.ElementAt(7)), suicides = Convert.ToInt32(stats.Values.ElementAt(8)), wounded = Convert.ToInt32(stats.Values.ElementAt(9)), c4thrown = Convert.ToInt32(stats.Values.ElementAt(10)), satchelsthrown = Convert.ToInt32(stats.Values.ElementAt(11)), rocketsfired = Convert.ToInt32(stats.Values.ElementAt(12)), tcsdestroyed = Convert.ToInt32(stats.Values.ElementAt(13)), npcStats = new NPCStats {
                            chickens = Convert.ToInt32(stats.Values.ElementAt(14)), boars = Convert.ToInt32(stats.Values.ElementAt(15)), deers = Convert.ToInt32(stats.Values.ElementAt(16)), horses = Convert.ToInt32(stats.Values.ElementAt(17)), wolves = Convert.ToInt32(stats.Values.ElementAt(18)), bears = Convert.ToInt32(stats.Values.ElementAt(19)), scientists = Convert.ToInt32(stats.Values.ElementAt(20)), helicopters = Convert.ToInt32(stats.Values.ElementAt(21)), bradleys = Convert.ToInt32(stats.Values.ElementAt(22)),
                        }
                        , weaponStats = new WeaponStats {
                            ak47 = Convert.ToInt32(stats.Values.ElementAt(23)), lr300 = Convert.ToInt32(stats.Values.ElementAt(24)), m39 = Convert.ToInt32(stats.Values.ElementAt(25)), sar = Convert.ToInt32(stats.Values.ElementAt(26)), m249 = Convert.ToInt32(stats.Values.ElementAt(27)), hmlmg = Convert.ToInt32(stats.Values.ElementAt(28)), l96 = Convert.ToInt32(stats.Values.ElementAt(29)), bolt = Convert.ToInt32(stats.Values.ElementAt(30)), mp5 = Convert.ToInt32(stats.Values.ElementAt(31)), thompson = Convert.ToInt32(stats.Values.ElementAt(32)), custom = Convert.ToInt32(stats.Values.ElementAt(33)), pump = Convert.ToInt32(stats.Values.ElementAt(34)), doublebarrel = Convert.ToInt32(stats.Values.ElementAt(35)), spaz12 = Convert.ToInt32(stats.Values.ElementAt(36)), m92 = Convert.ToInt32(stats.Values.ElementAt(37)), python = Convert.ToInt32(stats.Values.ElementAt(38)), semipistol = Convert.ToInt32(stats.Values.ElementAt(39)), revolver = Convert.ToInt32(stats.Values.ElementAt(40)), waterpipe = Convert.ToInt32(stats.Values.ElementAt(41)), eoka = Convert.ToInt32(stats.Values.ElementAt(42)), compound = Convert.ToInt32(stats.Values.ElementAt(43)), crossbow = Convert.ToInt32(stats.Values.ElementAt(44)), bow = Convert.ToInt32(stats.Values.ElementAt(45)),
                        }
                        , hits = new BodyParts {
                            head = Convert.ToInt32(stats.Values.ElementAt(46)), torso = Convert.ToInt32(stats.Values.ElementAt(47)), lefthand = Convert.ToInt32(stats.Values.ElementAt(48)), righthand = Convert.ToInt32(stats.Values.ElementAt(49)), leftleg = Convert.ToInt32(stats.Values.ElementAt(50)), rightleg = Convert.ToInt32(stats.Values.ElementAt(51)), leftfoot = Convert.ToInt32(stats.Values.ElementAt(52)), rightfoot = Convert.ToInt32(stats.Values.ElementAt(53)),
                        }
                        ,
                    }
                    );
                }
                ;
                Sql overallquery = Sql.Builder.Append($"SELECT * FROM {config.serverPrefix}_stats_overall");
                SQL.Query(overallquery, connection, newlist => {
                    playerStatsOverall.Clear();
                    foreach (var stats in newlist) {
                        if (playerStatsOverall.ContainsKey(stats.Values.ElementAt(2).ToString())) continue;
                        playerStatsOverall.Add(stats.Values.ElementAt(2).ToString(), new PlayerStats {
                            name = stats.Values.ElementAt(1).ToString(), connections = Convert.ToInt32(stats.Values.ElementAt(3)), playtime = Convert.ToInt32(stats.Values.ElementAt(4)), kills = Convert.ToInt32(stats.Values.ElementAt(5)), deaths = Convert.ToInt32(stats.Values.ElementAt(6)), bfired = Convert.ToInt32(stats.Values.ElementAt(7)), suicides = Convert.ToInt32(stats.Values.ElementAt(8)), wounded = Convert.ToInt32(stats.Values.ElementAt(9)), c4thrown = Convert.ToInt32(stats.Values.ElementAt(10)), satchelsthrown = Convert.ToInt32(stats.Values.ElementAt(11)), rocketsfired = Convert.ToInt32(stats.Values.ElementAt(12)), tcsdestroyed = Convert.ToInt32(stats.Values.ElementAt(13)), npcStats = new NPCStats {
                                chickens = Convert.ToInt32(stats.Values.ElementAt(14)), boars = Convert.ToInt32(stats.Values.ElementAt(15)), deers = Convert.ToInt32(stats.Values.ElementAt(16)), horses = Convert.ToInt32(stats.Values.ElementAt(17)), wolves = Convert.ToInt32(stats.Values.ElementAt(18)), bears = Convert.ToInt32(stats.Values.ElementAt(19)), scientists = Convert.ToInt32(stats.Values.ElementAt(20)), helicopters = Convert.ToInt32(stats.Values.ElementAt(21)), bradleys = Convert.ToInt32(stats.Values.ElementAt(22)),
                            }
                            , weaponStats = new WeaponStats {
                                ak47 = Convert.ToInt32(stats.Values.ElementAt(23)), lr300 = Convert.ToInt32(stats.Values.ElementAt(24)), m39 = Convert.ToInt32(stats.Values.ElementAt(25)), sar = Convert.ToInt32(stats.Values.ElementAt(26)), m249 = Convert.ToInt32(stats.Values.ElementAt(27)), hmlmg = Convert.ToInt32(stats.Values.ElementAt(28)), l96 = Convert.ToInt32(stats.Values.ElementAt(29)), bolt = Convert.ToInt32(stats.Values.ElementAt(30)), mp5 = Convert.ToInt32(stats.Values.ElementAt(31)), thompson = Convert.ToInt32(stats.Values.ElementAt(32)), custom = Convert.ToInt32(stats.Values.ElementAt(33)), pump = Convert.ToInt32(stats.Values.ElementAt(34)), doublebarrel = Convert.ToInt32(stats.Values.ElementAt(35)), spaz12 = Convert.ToInt32(stats.Values.ElementAt(36)), m92 = Convert.ToInt32(stats.Values.ElementAt(37)), python = Convert.ToInt32(stats.Values.ElementAt(38)), semipistol = Convert.ToInt32(stats.Values.ElementAt(39)), revolver = Convert.ToInt32(stats.Values.ElementAt(40)), waterpipe = Convert.ToInt32(stats.Values.ElementAt(41)), eoka = Convert.ToInt32(stats.Values.ElementAt(42)), compound = Convert.ToInt32(stats.Values.ElementAt(43)), crossbow = Convert.ToInt32(stats.Values.ElementAt(44)), bow = Convert.ToInt32(stats.Values.ElementAt(45)),
                            }
                            , hits = new BodyParts {
                                head = Convert.ToInt32(stats.Values.ElementAt(46)), torso = Convert.ToInt32(stats.Values.ElementAt(47)), lefthand = Convert.ToInt32(stats.Values.ElementAt(48)), righthand = Convert.ToInt32(stats.Values.ElementAt(49)), leftleg = Convert.ToInt32(stats.Values.ElementAt(50)), rightleg = Convert.ToInt32(stats.Values.ElementAt(51)), leftfoot = Convert.ToInt32(stats.Values.ElementAt(52)), rightfoot = Convert.ToInt32(stats.Values.ElementAt(53)),
                            }
                            ,
                        }
                        );
                    }
                }
                );
            }
            );
            yield return null;
        }
#endregion
#region Commands
        [Command("stats.save")]
        private void SaveStatsCMD(IPlayer iPlayer, string command, string[] args) {
            if (!iPlayer.IsServer) return;
            if (args.Length > 0) {
                BasePlayer player = BasePlayer.FindAwakeOrSleeping(args[0]);
                if (player == null) return;
                SavePlayerStats(player);
            }
            else SaveAllStats();
        }
        [Command("stats")]
        private void MyStatsCMD(IPlayer iPlayer, string command, string[] args) {
            if (iPlayer.IsServer || !config.useIngameUI) return;
            BasePlayer player = iPlayer.Object as BasePlayer;
            CuiHelper.DestroyUi(player, "BetterStatsContainer");
            if (args.Length == 1) BetterStatsContainer(player, args[0]);
            else BetterStatsContainer(player, player.UserIDString);
        }
        [Command("destroyui")]
        private void DestroyUICMD(IPlayer iPlayer, string command, string[] args) {
            if (iPlayer.IsServer) return;
            BasePlayer player = iPlayer.Object as BasePlayer;
            CuiHelper.DestroyUi(player, args[0]);
        }
#endregion
#region UI
        private void BetterStatsContainer(BasePlayer player, string userId, int page = 1, bool wipeTable = true) {
            CuiHelper.DestroyUi(player, "BetterStatsContainer");
            if (wipeTable) {
                if (!playerStats.TryGetValue(userId, out stats)) {
                    player.ChatMessage(GetLang("PlayerNotFound"));
                    return;
                }
            }
            else {
                if (!playerStatsOverall.TryGetValue(userId, out stats)) {
                    player.ChatMessage(GetLang("PlayerNotFoundOverall"));
                    return;
                }
            }
            string playtime = "0";
            TimeSpan elapsedTime = new TimeSpan(0, stats.playtime, 0);
            int day = elapsedTime.Days;
            int hour = elapsedTime.Hours;
            int mins = elapsedTime.Minutes;
            if (day > 0) playtime = $"{day}d {hour}h {mins}m";
            else if (hour > 0) playtime = $"{hour}h {mins}m";
            else if (mins > 0) playtime = $"{mins}m";
            var container = new CuiElementContainer();
            container.Add(new CuiPanel {
                CursorEnabled = true, Image = {
                    Color = "0.1037736 0.101466 0.08762015 1"
                }
                , RectTransform = {
                    AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-630.789 -359.317", OffsetMax = "640.789 355.983"
                }
            }
            , "Overlay", "BetterStatsContainer");
            container.Add(new CuiElement {
                Name = "Grunge", Parent = "BetterStatsContainer", Components = {
                    new CuiRawImageComponent {
                        Color = "1 1 1 0.08", Png = ImageLibrary?.Call<string>("GetImage", "GrungeBackground"), Sprite = "assets/content/textures/generic/fulltransparent.tga"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
                    }
                }
            }
            );
            container.Add(new CuiPanel {
                CursorEnabled = false, Image = {
                    Color = "0.08235294 0.07843138 0.07450981 0.8"
                }
                , RectTransform = {
                    AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-635.797 -69", OffsetMax = "635.802 0"
                }
            }
            , "BetterStatsContainer", "BetterStatsHeader");
            container.Add(new CuiElement {
                Name = "HeaderTitle", Parent = "BetterStatsHeader", Components = {
                    new CuiTextComponent {
                        Text = GetLang("UITitle"), Font = "robotocondensed-bold.ttf", FontSize = 24, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "32.4 -18.171", OffsetMax = "211.821 18.17"
                    }
                }
            }
            );
            container.Add(new CuiButton {
                Button = {
                    Color = $"{(wipeTable ? "0.2392157 0.2941177 0.1529412 1" : "0.5882353 0.1843137 0.1254902 1")}", Command = $"reloadstats {userId} prev true"
                }
                , Text = {
                    Text = GetLang("UIWipeButton"), Font = "robotocondensed-bold.ttf", FontSize = 18, Align = TextAnchor.MiddleCenter, Color = $"{(wipeTable ? "0.6509804 0.8039216 0.3882353 1" : "0.7803922 0.5960785 0.5921569 1")}"
                }
                , RectTransform = {
                    AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-140.31 -16.657", OffsetMax = "-12.49 16.657"
                }
            }
            , "BetterStatsHeader", "WipeButton");
            container.Add(new CuiButton {
                Button = {
                    Color = $"{(!wipeTable ? "0.2392157 0.2941177 0.1529412 1" : "0.5882353 0.1843137 0.1254902 1")}", Command = $"reloadstats {userId} prev false"
                }
                , Text = {
                    Text = GetLang("UIOverallButton"), Font = "robotocondensed-bold.ttf", FontSize = 18, Align = TextAnchor.MiddleCenter, Color = $"{(!wipeTable ? "0.6509804 0.8039216 0.3882353 1" : "0.7803922 0.5960785 0.5921569 1")}"
                }
                , RectTransform = {
                    AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "8.89 -16.657", OffsetMax = "136.71 16.657"
                }
            }
            , "BetterStatsHeader", "OverallButton");
            container.Add(new CuiButton {
                Button = {
                    Color = "0.5882353 0.1843137 0.1254902 1", Command = "destroyui BetterStatsContainer"
                }
                , RectTransform = {
                    AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-141.221 -13.031", OffsetMax = "-31.979 16.657"
                }
            }
            , "BetterStatsHeader", "CloseButton");
            container.Add(new CuiElement {
                Name = "CloseText", Parent = "CloseButton", Components = {
                    new CuiTextComponent {
                        Text = GetLang("UIExitButton"), Font = "robotocondensed-bold.ttf", FontSize = 18, Align = TextAnchor.MiddleLeft, Color = "0.7803922 0.5960785 0.5921569 1"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-63.06 -15", OffsetMax = "0 15"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Name = "Image_9016", Parent = "CloseButton", Components = {
                    new CuiTextComponent {
                        Text = "X", Font = "robotocondensed-bold.ttf", FontSize = 13, Align = TextAnchor.MiddleCenter, Color = "0.7803922 0.5960785 0.5921569 1"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "24.169 -7.365", OffsetMax = "38.9 7.365"
                    }
                }
            }
            );
            container.Add(new CuiPanel {
                CursorEnabled = false, Image = {
                    Color = "0.08235294 0.07843138 0.07450981 0.8078431"
                }
                , RectTransform = {
                    AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-615.245 -295.746", OffsetMax = "-313.755 271.718"
                }
            }
            , "BetterStatsContainer", "PlayerViewPanel");
            container.Add(new CuiPanel {
                CursorEnabled = false, Image = {
                    Color = "0.08235294 0.07843138 0.07450981 1"
                }
                , RectTransform = {
                    AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-150.746 -37", OffsetMax = "150.744 0"
                }
            }
            , "PlayerViewPanel", "PlayerViewHeader");
            container.Add(new CuiElement {
                Name = "PlayerViewHeaderText", Parent = "PlayerViewHeader", Components = {
                    new CuiTextComponent {
                        Text = $"{stats.name}", Font = "robotocondensed-bold.ttf", FontSize = 22, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-139.065 -15.214", OffsetMax = "150.744 15.213"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Name = "PlayerImage", Parent = "PlayerViewPanel", Components = {
                    new CuiRawImageComponent {
                        Color = "1 1 1 1", Png = ImageLibrary?.Call<string>("GetImage", "PlayerImage"), Sprite = "assets/content/textures/generic/fulltransparent.tga"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-90.286 -269.7", OffsetMax = "90.284 229.7"
                    }
                }
            }
            );
            container.Add(new CuiPanel {
                CursorEnabled = false, Image = {
     
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху