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

FREE PlaytimeTracker : 0.1.7 0.1.7

Нет прав для скачивания
C#:
using System;
using System.Linq;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;

namespace Oxide.Plugins
{
    [Info("Playtime Tracker", "k1lly0u", "0.1.7", ResourceId = 2125)]
    [Description("Tracks playtime and AFK time of players with a built-in reward system")]
    class PlaytimeTracker : CovalencePlugin
    {
        #region Fields
        [PluginReference]
        Plugin Economics, Economy, ServerRewards, UEconomics;

        PlayData playData;
        private DynamicConfigFile TimeData;

        PermData permData;
        private DynamicConfigFile PermissionData;

        RefData referData;
        private DynamicConfigFile ReferralData;

        private Dictionary<string, TimeInfo> timeCache;
        private Dictionary<string, Timer> updateTimers;
        private Dictionary<string, double> timeStamps;
        private Dictionary<string, GenericPosition> posCache;

        private Timer saveTimer;
        private bool canIssueRewards;
        #endregion

        #region Oxide Hooks
        void Init()
        {
            TimeData = Interface.Oxide.DataFileSystem.GetFile("PTTracker/playtime_data");
            PermissionData = Interface.Oxide.DataFileSystem.GetFile("PTTracker/permission_data");
            ReferralData = Interface.Oxide.DataFileSystem.GetFile("PTTracker/referral_data");

            lang.RegisterMessages(Messages, this);

            timeCache = new Dictionary<string, TimeInfo>();
            timeStamps = new Dictionary<string, double>();
            updateTimers = new Dictionary<string, Timer>();
            posCache = new Dictionary<string, GenericPosition>();
        }
        void OnServerInitialized()
        {
            LoadVariables();
            LoadData();
            HasValidRewardSystem();
            SaveLoop();

            foreach (var perm in permData.permissions)
                permission.RegisterPermission(perm.Key, this);

            foreach (var player in players.Connected)
                OnUserConnected(player);
        }
        void OnUserConnected(IPlayer player)
        {
            InitPlayerData(player);
        }
        void OnUserDisconnected(IPlayer player)
        {
            if (updateTimers.ContainsKey(player.Id))
            {
                if (updateTimers[player.Id] != null)
                    updateTimers[player.Id].Destroy();
                updateTimers.Remove(player.Id);
            }

            AddTime(player);

            if (posCache.ContainsKey(player.Id))
                posCache.Remove(player.Id);

            if (timeStamps.ContainsKey(player.Id))
                timeStamps.Remove(player.Id);
        }
        void Unload()
        {
            if (saveTimer != null)
                saveTimer.Destroy();
            foreach (var player in players.Connected)
                OnUserDisconnected(player);

            SaveData();
        }
        void HasValidRewardSystem(int attempts = 0)
        {
            bool success = false;
            if (configData.RewardSystem.Enabled)
            {
#if RUST
                if (configData.RewardSystem.RewardPlugins.Rust.ServerRewards && ServerRewards)
                    success = true;
                else if (configData.RewardSystem.RewardPlugins.Rust.Economics && Economics)
                    success = true;
#endif
#if HURTWORLD
                if (configData.RewardSystem.RewardPlugins.Hurtworld.Economy && Economy)
                    success = true;
#endif
                if (configData.RewardSystem.RewardPlugins.Universal.UEconomics && UEconomics)
                    success = true;
                if (!success)
                {
                    if (attempts == 0)
                    {
                        PrintWarning("Unable to find any supported reward plugins.This may be caused by PTT loading before them.Will check again in 1 minute");
                        timer.In(60, () => HasValidRewardSystem(1));
                        return;
                    }
                    PrintWarning("Still unable to find any supported reward plugins.Rewards will not be issued!");
                }
            }

            canIssueRewards = success;
        }
        #endregion

        #region Time Tracking
        static double GrabCurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
        void InitPlayerData(IPlayer player)
        {
            var ID = player.Id;
            var time = GrabCurrentTime();
            CheckForData(player);
            if (!timeStamps.ContainsKey(ID))
                timeStamps.Add(ID, time);
            else timeStamps[ID] = time;
            ResetTimer(player, true);
        }
        void ResetTimer(IPlayer player, bool isNew = false)
        {
            AddTime(player);
            if (isNew && !updateTimers.ContainsKey(player.Id))
            {
                updateTimers.Add(player.Id, timer.Once(60, () => ResetTimer(player)));
            }
            else updateTimers[player.Id] = timer.Once(60, () => ResetTimer(player));
        }
        void CheckForData(IPlayer player)
        {
            if (!timeCache.ContainsKey(player.Id))
                timeCache.Add(player.Id, new TimeInfo
                {
                    afkTime = 0,
                    lastReward = 0,
                    referrals = 0,
                    playTime = 0
                });

            if (!timeStamps.ContainsKey(player.Id))
                timeStamps.Add(player.Id, GrabCurrentTime());
        }
        void AddTime(IPlayer player)
        {
            if (!player.IsConnected)
                return;

            var ID = player.Id;
            bool isAFK = false;
            CheckForData(player);

            var time = GrabCurrentTime() - timeStamps[ID];
            timeStamps[ID] = GrabCurrentTime();

            if (configData.Options.TrackAFKTime)
            {
                isAFK = CheckPosition(player);
                AddPosition(player);
            }
            if (isAFK)
                timeCache[ID].afkTime += time;
            else
                timeCache[ID].playTime += time;

            if (canIssueRewards)
                CheckForReward(player);
        }

        void AddPosition(IPlayer player)
        {
            if (player?.Position() == null)
                return;
            if (!posCache.ContainsKey(player.Id))
                posCache.Add(player.Id, player.Position());
            else posCache[player.Id] = player.Position();
        }

        bool CheckPosition(IPlayer player)
        {
            if (player?.Position() == null)
                return false;
            if (posCache.ContainsKey(player.Id))
            {
                if (posCache[player.Id].Equals(player.Position()))
                    return true;
            }
            return false;
        }
        #endregion

        #region Reward Management
        void CheckForReward(IPlayer player)
        {
            if (timeCache[player.Id].playTime >= (timeCache[player.Id].lastReward + configData.RewardSystem.Points.Playtime_PointTimer))
            {
                AddPoints(player, configData.RewardSystem.Points.Playtime_Points);
                timeCache[player.Id].lastReward += configData.RewardSystem.Points.Playtime_PointTimer;
            }
        }
        void AddPoints(IPlayer player, int amount)
        {
            object multiplier = GetRewardMultiplier(player);
            if (multiplier == null) multiplier = 1f;
            amount = Convert.ToInt32(Math.Floor(amount * (float)multiplier));
            if (amount == 0) amount = 1;

            string currency = Msg("currencyNameEco", player.Id);
            #if RUST
            if (ServerRewards && configData.RewardSystem.RewardPlugins.Rust.ServerRewards)
            {
                ServerRewards?.Call("AddPoints", ulong.Parse(player.Id), amount);
                currency = Msg("currencyNameRP", player.Id);
            }

            if (Economics && configData.RewardSystem.RewardPlugins.Rust.Economics)
                Economics?.Call("Deposit", player.Id, (double)amount);
            #endif

            #if HURTWORLD
            if (Economy && configData.RewardSystem.RewardPlugins.Hurtworld.Economy)
                Economy?.Call("AddMoney", player.Object as PlayerSession, (double)amount);
            #endif
            if (UEconomics && configData.RewardSystem.RewardPlugins.Universal.UEconomics)
                UEconomics?.Call("Deposit", player.Id, amount);

            if (configData.RewardSystem.SendDepositMessage)
                player.Reply(string.Format(Msg("depositMsg", player.Id), amount, currency));
        }
        object GetRewardMultiplier(IPlayer player)
        {
            foreach (var perm in permData.permissions)
                if (permission.UserHasPermission(player.Id, perm.Key))
                    return perm.Value;
            return null;
        }
        private string GetPlaytimeClock(double time)
        {
            TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
            var days = dateDifference.Days;
            var hours = dateDifference.Hours;
            hours += (days * 24);
            var mins = dateDifference.Minutes;
            var secs = dateDifference.Seconds;
            return string.Format("{0:00}:{1:00}:{2:00}", hours, mins, secs);
        }
        #endregion

        #region API
        object GetPlayTime(string playerid)
        {
            if (timeCache.ContainsKey(playerid))
            {
                if (timeStamps.ContainsKey(playerid))
                {
                    var additional = GrabCurrentTime() - timeStamps[playerid];
                    return timeCache[playerid].playTime + additional;
                }
                else return timeCache[playerid].playTime;
            }
            else return null;
        }
        object GetAFKTime(string playerid)
        {
            if (timeCache.ContainsKey(playerid))
                return timeCache[playerid].afkTime;
            else return null;
        }
        object GetReferrals(string playerid)
        {
            if (timeCache.ContainsKey(playerid))
                return timeCache[playerid].referrals;
            else return null;
        }
        #endregion

        #region Commands
        [Command("playtime")]
        void cmdPlaytime(IPlayer player, string command, string[] args)
        {
            if(args == null || args.Length == 0)
            {
                var time = GetPlayTime(player.Id);
                if (time != null)
                {
                    player.Reply(GetPlaytimeClock((double)time));
                    player.Reply(Msg("topPTSyn", player.Id));
                    return;
                }
                else player.Reply(Msg("notime", player.Id));
            }
            if (args.Length >= 1)
            {
                if (args[0].ToLower() == "top")
                {
                    string topPlayers = Msg("topPlaytime", player.Id);
                    int amount = 10;
                    if (args.Length > 1)
                    {
                        if (!int.TryParse(args[1], out amount))
                            amount = 10;
                    }
                    foreach (var topTime in timeCache.OrderByDescending(x => x.Value.playTime).Take(amount))
                    {
                        double playTime = topTime.Value.playTime;
                        if (timeStamps.ContainsKey(topTime.Key))
                            playTime += GrabCurrentTime() - timeStamps[topTime.Key];
                        topPlayers += $"\n{players.FindPlayerById(topTime.Key)?.Name ?? "Unnamed"} - {GetPlaytimeClock(playTime)}";
                    }
                    player.Reply(topPlayers);
                    return;
                }
                if (args[0].ToLower() == "all")
                {
                    string topPlayers = Msg("topPlaytime");
                    foreach (var topTime in timeCache.OrderByDescending(x => x.Value.playTime))
                    {
                        double playTime = topTime.Value.playTime;
                        if (timeStamps.ContainsKey(topTime.Key))
                            playTime += GrabCurrentTime() - timeStamps[topTime.Key];
                        topPlayers += $"\n{players.FindPlayerById(topTime.Key)?.Name ?? "Unnamed"} - {GetPlaytimeClock(playTime)}";
                    }
                    player.Reply(topPlayers);
                    return;
                }
                if (player.IsAdmin)
                {
                    var target = players.FindPlayer(args[0]);
                    if (target != null)
                    {
                        var time = GetPlayTime(target.Id);
                        if (time != null)
                        {
                            player.Reply($"{target.Name} {GetPlaytimeClock((double)time)}");
                            return;
                        }
                        else player.Reply(Msg("notimetarget", player.Id));
                    }
                    else player.Reply(Msg("notarget", player.Id));
                }
            }
        }
        [Command("ptt")]
        void cmdPTT(IPlayer player, string command, string[] args)
        {
            if (player.IsAdmin)
            {
                if (args == null || args.Length == 0)
                {
                    player.Reply(Msg("ptt",player.Id));
                    player.Reply(Msg("addsyn",player.Id));
                    player.Reply(Msg("remsyn",player.Id));
                    player.Reply(Msg("listsyn",player.Id));
                    return;
                }
                switch (args[0].ToLower())
                {
                    case "add":
                        if (args.Length == 3)
                        {
                            float multiplier;
                            if (float.TryParse(args[2], out multiplier))
                            {
                                var perm = args[1].ToLower();
                                if (!perm.StartsWith("playtimetracker."))
                                    perm = "playtimetracker." + perm;
                                if (!permData.permissions.ContainsKey(perm))
                                {
                                    permData.permissions.Add(perm, multiplier);
                                    permission.RegisterPermission(perm, this);
                                    SavePermission();
                                    player.Reply(string.Format(Msg("createsucc",player.Id), perm, multiplier));
                                    return;
                                }
                                else player.Reply(string.Format(Msg("permexist",player.Id), perm));
                            }
                            else player.Reply(Msg("nomulti",player.Id));
                        }
                        else player.Reply("/ptt add <permissionname> <multiplier>");
                        return;
                    case "remove":
                        if (args.Length == 2)
                        {
                            if (permData.permissions.ContainsKey(args[1]))
                            {
                                permData.permissions.Remove(args[1]);
                                SavePermission();
                                player.Reply(string.Format(Msg("permrem",player.Id), args[1]));
                            }
                            else player.Reply(string.Format(Msg("noperm",player.Id), args[1]));
                        }
                        else player.Reply("/ptt remove <permissionname>");
                        return;
                    case "list":
                        player.Reply(Msg("permmulti",player.Id));
                        foreach (var perm in permData.permissions)
                            player.Reply($"{perm.Key} | {perm.Value}");
                        return;
                    default:
                        break;
                }
            }
        }

        [Command("refer")]
        void cmdRefer(IPlayer player, string command, string[] args)
        {
            if (configData.ReferralSystem.UseReferralSystem)
            {
                if (args == null || args.Length == 0)
                {
                    player.Reply(Msg("refsyn",player.Id));
                    return;
                }
                if (referData.referrals.Contains(player.Id))
                {
                    player.Reply(Msg("alreadyref",player.Id));
                    return;
                }
                if (args.Length >= 1)
                {
                    IPlayer referee = players.FindPlayer(args[0]);
                    if (referee != null)
                    {
                        if (referee.Id == player.Id)
                        {
                            player.Reply(Msg("noself",player.Id));
                            return;
                        }
                        if (timeCache.ContainsKey(referee.Id))
                            timeCache[referee.Id].referrals++;

                        referData.referrals.Add(player.Id);
                        if (canIssueRewards && configData.ReferralSystem.IssueRewardForReferral)
                        {
                            AddPoints(player, configData.RewardSystem.Points.Referral_JoinPoints);
                            AddPoints(referee, configData.RewardSystem.Points.Referral_InvitePoints);

                            if (referee.IsConnected)
                                referee.Reply(string.Format(Msg("referacceptref", referee.Id), player.Name, configData.RewardSystem.Points.Referral_InvitePoints));
                            player.Reply(string.Format(Msg("referacceptplayer", player.Id), configData.RewardSystem.Points.Referral_JoinPoints));
                        }
                        else
                        {
                            if (referee.IsConnected)
                                referee.Reply(string.Format(Msg("referaccept1ref",referee.Id),player.Name));
                            player.Reply(Msg("referaccept1player",player.Id));
                        }
                    }
                    else player.Reply(Msg("noplayer", player.Id));
                }
            }
        }
        #endregion

        #region Config
        class Rewards
        {
            public bool Enabled { get; set; }
            public RPlugins RewardPlugins { get; set; }
            public Points Points { get; set; }
            public bool SendDepositMessage { get; set; }
        }
        class RPlugins
        {
            public RRust Rust { get; set; }
            public RHurtworld Hurtworld { get; set; }
            public RUniversal Universal { get; set; }
        }
        class RRust
        {
            public bool ServerRewards { get; set; }
            public bool Economics { get; set; }
        }
        class RHurtworld
        {
            public bool Economy { get; set; }
        }
        class RUniversal
        {
            public bool UEconomics { get; set; }
        }
        class Referrals
        {
            public bool UseReferralSystem { get; set; }
            public bool IssueRewardForReferral { get; set; }
        }
        class Points
        {
            public int Playtime_PointTimer { get; set; }
            public int Playtime_Points { get; set; }
            public int Referral_JoinPoints { get; set; }
            public int Referral_InvitePoints { get; set; }
        }
        class Options
        {
            public bool TrackAFKTime { get; set; }
            public int SaveTimer { get; set; }
        }
        private ConfigData configData;
        class ConfigData
        {
            public Rewards RewardSystem { get; set; }
            public Referrals ReferralSystem { get; set; }
            public Options Options { get; set; }
        }
        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }
        protected override void LoadDefaultConfig()
        {
            var config = new ConfigData
            {
                Options = new Options
                {
                    SaveTimer = 15,
                    TrackAFKTime = true
                },
                RewardSystem = new Rewards
                {
                    Enabled = true,
                    RewardPlugins = new RPlugins
                    {
                        Hurtworld = new RHurtworld
                        {
                            Economy = false
                        },
                        Rust = new RRust
                        {
                            Economics = false,
                            ServerRewards = true
                        },
                        Universal = new RUniversal
                        {
                            UEconomics = false
                        }
                    },
                    Points = new Points
                    {
                        Playtime_Points = 5,
                        Playtime_PointTimer = 3600,
                        Referral_InvitePoints = 5,
                        Referral_JoinPoints = 3
                    },
                    SendDepositMessage = true
                },
                ReferralSystem = new Referrals
                {
                    IssueRewardForReferral = true,
                    UseReferralSystem = true
                }
            };
            SaveConfig(config);
        }
        private void LoadConfigVariables() => configData = Config.ReadObject<ConfigData>();
        void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
#endregion

        #region Data Management
        void SaveLoop() => saveTimer = timer.Once(configData.Options.SaveTimer * 60, () => { SaveData(); SaveLoop(); });
        void SaveData()
        {
            playData.timeData = timeCache;
            TimeData.WriteObject(playData);
            ReferralData.WriteObject(referData);
        }
        void SavePermission()
        {
            PermissionData.WriteObject(permData);
        }
        void LoadData()
        {
            try
            {
                playData = TimeData.ReadObject<PlayData>();
                timeCache = playData.timeData;
            }
            catch
            {
                playData = new PlayData();
            }
            try
            {
                referData = ReferralData.ReadObject<RefData>();
            }
            catch
            {
                referData = new RefData();
            }
            try
            {
                permData = PermissionData.ReadObject<PermData>();
            }
            catch
            {
                permData = new PermData();
            }
        }
        class PlayData
        {
            public Dictionary<string, TimeInfo> timeData = new Dictionary<string, TimeInfo>();
        }
        class TimeInfo
        {
            public double playTime;
            public double afkTime;
            public double lastReward;
            public int referrals;
        }
        class PermData
        {
            public Dictionary<string, float> permissions = new Dictionary<string, float>();
        }
        class RefData
        {
            public List<string> referrals = new List<string>();
        }
        #endregion

        #region Localization
        string Msg(string key, string playerid = null) => lang.GetMessage(key, this, playerid);

        Dictionary<string, string> Messages = new Dictionary<string, string>
        {
            {"noplayer", "Unable to find a player with that name."},
            {"referaccept1player", "Your referral has been accepted"},
            {"referaccept1ref", "{0} has acknowledged a referral from you"},
            {"referacceptplayer", "Your referral has been accepted and you have received {0} points"},
            {"referacceptref", "{0} has acknowledged a referral from you and you have received {1} points"},
            {"noself", "You can not refer yourself..."},
            {"alreadyref", "You have already acknowledged a referral"},
            {"refsyn", "/refer <playername> - Acknowledge a referral from <playername>"},
            {"permmulti", "permission | multiplier"},
            {"noperm", "The permission {0} does not exist"},
            {"permrem", "You have successfully removed the permission {0}"},
            {"nomulti", "You must enter a multiplier"},
            {"permexist", "The permission '{0}' already exists"},
            {"createsucc", "You have successfully created a new reward multiplier.Permission: {0}, Multiplier {1}"},
            {"ptt", "Create custom permissions with reward multipliers for VIP players"},
            {"addsyn", "/ptt add <permissionname> <multiplier> - Add a new reward multiplier"},
            {"remsyn", "/ptt remove <permissionname> - Remove reward multiplier"},
            {"listsyn", "/ptt list - List available permission and their multipliers"},
            {"notime", "Unable to get your playtime" },
            {"notimetarget", "Unable to get that players playtime" },
            {"notarget", "Unable to find the specified player" },
            {"currencyNameRP", "RP" },
            {"currencyNameEco", "Coins" },
            {"depositMsg", "{0} {1} have been deposited to your account!" },
            {"topPlaytime", "Top Playtimes:" },
            {"topPTSyn", "You can see the top scoring playtimes by typing \"/playtime top (optional:number)\"" }
        };
        #endregion
    }
}

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