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

FREE PhonesPlus : 1.0.2 1.0.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6

using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{

    [Info("Phones Plus", "mr01sam", "1.0.2")]
    [Description("Adds notifications, messages, caller ID and more features to phones.")]
    public class PhonesPlus : CovalencePlugin
    {
        private static PhonesPlus PLUGIN;

        private const string PermissionUse = "phonesplus.use";
        private const string PermissionAdmin = "phonesplus.admin";

        /* For internal use */
        private const string PermissionTemp = "phonesplus.temp";

        [PluginReference]
        Plugin ImageLibrary;

        PhoneManager phoneManager;


        #region Localization
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["UI title history"] = "HISTORY",
                ["UI title messages"] = "MESSAGES",
                ["UI title clear"] = "CLEAR",
                ["UI title track"] = "TRACK PHONE",
                ["UI title untrack"] = "UNTRACK PHONE",
                ["UI title prompt"] = "No answer? Leave a message:",
                ["HUD incoming"] = "Incoming call from {0}",
                ["History missed"] = "Missed call from {0}",
                ["History outgoing"] = "Outgoing call to {0}",
                ["History answered"] = "Answered call from {0}",
                ["Time minutes"] = "{0} minutes ago",
                ["Time hours"] = "{0} hours ago",
                ["Time days"] = "{0} days ago",
                ["Usage"] = "Usage: {0}",
                ["Notifications on"] = "You will receive incoming call notifications from tracked phones",
                ["Notifications off"] = "You will no longer receive incoming call notifications from tracked phones",
                ["Indicators on"] = "Indicators will be displayed on the HUD for tracked phones",
                ["Indicators off"] = "Indicators will no longer be displayed on the HUD for tracked phones",
                ["No permission"] = "You do not have permission to use that command",
                ["Tracking on"] = "Now tracking phone {0}",
                ["Tracking off"] = "Stopped tracking phone {0}",
                ["Reset ui"] = "Reset UI",
                ["Reset tracked"] = "Reset tracked phone records",
                ["No messages"] = "No recent messages",
                ["No history"] = "No recent calls",
                ["Clear history"] = "Cleared history for {0}",
                ["Clear trackers"] = "Cleared trackers for {0}",
                ["Clear messages"] = "Cleared messages for {0}"
            }, this);
        }
        #endregion

        #region Configuration

        private Configuration config;

        private class Configuration
        {
            [JsonProperty(PropertyName = "Enable incoming call notifications (true/false)")]
            public bool EnableIncomingCallNotifications { get; set; } = true;

            [JsonProperty(PropertyName = "Hourly message limit")]
            public int HourlyMessageLimit { get; set; } = 50;

            [JsonProperty(PropertyName = "HUD Notification")]
            public NotificationHUD HudNotification = new NotificationHUD
            {
                AnchorMin = "0.4 0.87",
                AnchorMax = "0.6 0.95",
                BackgroundColor = "0.4 0.4 0.4"
            };

            [JsonProperty(PropertyName = "HUD Call Indicator")]
            public IndicatorHUD HudCallIndicator = new IndicatorHUD
            {
                AnchorMin = "0.655 0.90",
                AnchorMax = "0.675 0.95",
                ImageColor = "0.5 1 0.5 0.5"
            };

            [JsonProperty(PropertyName = "HUD Message Indicator")]
            public IndicatorHUD HudMessageIndicator = new IndicatorHUD
            {
                AnchorMin = "0.68 0.90",
                AnchorMax = "0.70 0.95",
                ImageColor = "0.5 0.5 1 0.5"
            };

            public class NotificationHUD
            {
                [JsonProperty(PropertyName = "Anchor min")]
                public string AnchorMin;
                [JsonProperty(PropertyName = "Anchor max")]
                public string AnchorMax;
                [JsonProperty(PropertyName = "Background color")]
                public string BackgroundColor;
            }

            public class IndicatorHUD
            {
                [JsonProperty(PropertyName = "Anchor min")]
                public string AnchorMin;
                [JsonProperty(PropertyName = "Anchor max")]
                public string AnchorMax;
                [JsonProperty(PropertyName = "Image color")]
                public string ImageColor;
            }

            public class HistoryUI
            {
                [JsonProperty(PropertyName = "Entry background color")]
                public string EntryBackgroundColor = "0.9 0.9 0.9 0.9";
                [JsonProperty(PropertyName = "Font color")]
                public string FontColor = "1 1 1 1";
            }

            public class MessagesUI
            {
                [JsonProperty(PropertyName = "Entry background color")]
                public string EntryBackgroundColor = "0.9 0.9 0.9 0.9";
            }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();

            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintError("Your configuration file contains an error.Using default configuration values.");
                LoadDefaultConfig();
            }

            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultConfig() => config = new Configuration();


        #endregion

        #region Commands

        private Dictionary<string, ChatCmd> commands = new Dictionary<string, ChatCmd>();

        void InitCommands()
        {
            commands.Add("help", new ChatCmd
            {
                perms = new List<string>() { PermissionUse },
                function = (IPlayer player, string command, string[] args) => { cmd_phone_help(player, command, args); }
            });
            commands.Add("set", new ChatCmd
            {
                usages = new List<string>() { "<notifications/indicators> <true/false>" },
                perms = new List<string>() { PermissionUse },
                function = (IPlayer player, string command, string[] args) => { cmd_phone_set(player, command, args); }
            });
            commands.Add("reset", new ChatCmd
            {
                usages = new List<string>() { "<ui/tracked>" },
                perms = new List<string>() { PermissionUse },
                function = (IPlayer player, string command, string[] args) => { cmd_phone_reset(player, command, args); }
            });
            commands.Add("clear", new ChatCmd
            {
                usages = new List<string>() { "<trackers/messages/history> <phonenumber>" },
                perms = new List<string>() { PermissionAdmin },
                function = (IPlayer player, string command, string[] args) => { cmd_phone_clear(player, command, args); }
            });
        }

        class ChatCmd
        {
            public string prefix = "";
            public List<string> usages = new List<string>();
            public List<string> perms = new List<string>();
            public Action<IPlayer, string, string[]> function;

            public bool HasPerms(string id, PhonesPlus plugin)
            {
                foreach (string perm in perms)
                    if (plugin.permission.UserHasPermission(id, perm))
                        return true;
                return false;
            }

            public string Usage(string prefix)
            {
                string message = "";
                if (usages.Count > 0)
                {
                    string last = usages.Last();
                    foreach (string usg in usages)
                    {
                        message += string.Format("{0} {1}", prefix, usg);
                        if (!usg.Equals(last))
                            message += ", ";
                    }
                }
                else
                {
                    message = prefix;
                }

                return message;
            }
        }

        [Command("phone")]
        private void cmd_phone(IPlayer player, string command, string[] args)
        {
            if (args.Length >= 1)
            {
                string prefix = args[0].ToLower();
                if (commands.ContainsKey(prefix))
                {
                    args = args.Skip(1).ToArray();

                    ChatCmd cmd = commands[prefix];
                    if (cmd.HasPerms(player.Id, this))
                    {
                        try
                        {
                            commands[prefix].function(player, command, args);
                        }
                        catch (Exception)
                        {
                            player.Reply(string.Format(lang.GetMessage("Usage", this, player.Id), "phone " + cmd.Usage(prefix)));
                        }
                        return;
                    }
                    else
                    {
                        /* No perms */
                        player.Reply(lang.GetMessage("No permission", this, player.Id));
                    }
                }
            }
            else
            {
                if (permission.UserHasPermission(player.Id, PermissionUse))
                {
                    cmd_phone_help(player, command, args);
                }
                else
                {
                    player.Reply(lang.GetMessage("No permission", this, player.Id));
                }
            }
        }

        #region User Commands

        [Command("phone.set"), Permission(PermissionUse)]
        private void cmd_phone_set(IPlayer player, string command, string[] args)
        {
            bool value = bool.Parse(args[1]);
            switch (args[0].ToLower())
            {
                case "notifications":
                    phoneManager.SetPreference(ulong.Parse(player.Id), "notifications", value);
                    if (value)
                        player.Reply(lang.GetMessage("Notifications on", this, player.Id));
                    else
                        player.Reply(lang.GetMessage("Notifications off", this, player.Id));
                    break;
                case "indicators":
                    phoneManager.SetPreference(ulong.Parse(player.Id), "indicators", value);
                    if (value)
                        player.Reply(lang.GetMessage("Indicators on", this, player.Id));
                    else
                        player.Reply(lang.GetMessage("Indicators off", this, player.Id));
                    ShowUnreadIndicator(BasePlayer.FindByID(ulong.Parse(player.Id)));
                    ShowCallIndicator(BasePlayer.FindByID(ulong.Parse(player.Id)));
                    break;
                default:
                    break;
            }
        }

        [Command("phone.reset"), Permission(PermissionUse)]
        private void cmd_phone_reset(IPlayer player, string command, string[] args)
        {
            BasePlayer entity = BasePlayer.FindByID(ulong.Parse(player.Id));
            switch (args[0].ToLower())
            {
                case "ui":
                    HideAllUI(entity);
                    ShowCallIndicator(entity);
                    ShowUnreadIndicator(entity);
                    player.Reply(lang.GetMessage("Reset ui", this, player.Id));
                    break;
                case "tracked":
                    foreach (uint id in phoneManager.GetTrackedPhones(entity.userID))
                    {
                        RegisteredPhone phone = phoneManager.FindPhoneByID(id);
                        if (phone != null)
                            phoneManager.UntrackPhone(entity, phone.GetNumber());
                    }

                    phoneManager.UpdatePhoneMessageCount(entity.userID, 0);
                    phoneManager.UpdatePhoneRecordsCount(entity.userID, 0);
                    player.Reply(lang.GetMessage("Reset tracked", this, player.Id));
                    ShowUnreadIndicator(entity);
                    ShowCallIndicator(entity);
                    break;
                default:
                    break;
            }
        }

        [Command("phone.help"), Permission(PermissionUse)]
        private void cmd_phone_help(IPlayer player, string command, string[] args)
        {
            string size = "16";
            string cmdList = FormatTxt("Phones", "ca2a13", size) + FormatTxt("Plus", "ca2a13", size) + "\n";
            foreach (string prefix in commands.Keys)
            {
                ChatCmd cmd = commands[prefix];
                if (cmd.HasPerms(player.Id, this))
                    cmdList += "phone " + cmd.Usage(prefix) + "\n";
            }
            player.Reply(cmdList);
        }

        #endregion

        #region UI Commands
        [Command("phone.message"), Permission(PermissionTemp)]
        private void cmd_phone_message(IPlayer player, string command, string[] args)
        {
            int senderNumber = int.Parse(args[0]);
            int targetNumber = int.Parse(args[1]);
            string text = "";
            if (args.Length > 2 && !phoneManager.ExceededMessageLimit(ulong.Parse(player.Id)))
            {
                for (int i = 2; i < args.Length; i++)
                {
                    if (i == 2)
                        args[i] = args[i].TitleCase();
                    text += args[i];
                    if (i < args.Length - 1)
                        text += " ";
                }
                CuiHelper.DestroyUi(BasePlayer.FindByID(ulong.Parse(player.Id)), "phonesInputOverlay");
                if (text.Length > 0)
                {
                    phoneManager.IncrementMessageUse(ulong.Parse(player.Id));
                    phoneManager.LeaveMessage(senderNumber, targetNumber, text);
                }
            }
            CuiHelper.DestroyUi(BasePlayer.FindByID(ulong.Parse(player.Id)), "phonesInputOverlay");
        }

        [Command("phone.track"), Permission(PermissionTemp)]
        private void cmd_phone_track(IPlayer player, string command, string[] args)
        {
            int phoneNumber = int.Parse(args[0]);

            RegisteredPhone phone = phoneManager.FindPhoneByNumber(phoneNumber);
            if (phone != null)
            {
                BasePlayer target = BasePlayer.FindByID(ulong.Parse(player.Id));
                if (phoneManager.TrackPhone(target, phoneNumber))
                    player.Reply(string.Format(lang.GetMessage("Tracking on", this, player.Id), phoneNumber));
                ShowPhoneUI(target, phone);
            }
        }

        [Command("phone.untrack"), Permission(PermissionTemp)]
        private void cmd_phone_untrack(IPlayer player, string command, string[] args)
        {
            int phoneNumber = int.Parse(args[0]);

            RegisteredPhone phone = phoneManager.FindPhoneByNumber(phoneNumber);
            if (phone != null)
            {
                BasePlayer target = BasePlayer.FindByID(ulong.Parse(player.Id));
                if (phoneManager.UntrackPhone(target, phoneNumber))
                    player.Reply(string.Format(lang.GetMessage("Tracking off", this, player.Id), phoneNumber));
                ShowPhoneUI(target, phone);
            }
        }

        [Command("phone.clear"), Permission(PermissionTemp)]
        private void cmd_phone_clear(IPlayer player, string command, string[] args)
        {
            int number = int.Parse(args[1]);
            RegisteredPhone phone = phoneManager.FindPhoneByNumber(number);
            BasePlayer entity = BasePlayer.FindByID(ulong.Parse(player.Id));
            switch (args[0].ToLower())
            {
                case "messages":
                    phoneManager.ClearMessages(phone);
                    if (!phoneManager.IsStateEqualTo(entity, 0))
                        ShowPhoneUI(entity, phone);
                    else
                        player.Reply(string.Format(lang.GetMessage("Clear messages", this, player.Id), phone.GetIdentity()));
                    break;
                case "history":
                    phoneManager.ClearHistory(phone);
                    if (!phoneManager.IsStateEqualTo(entity, 0))
                        ShowPhoneUI(entity, phone);
                    else
                        player.Reply(string.Format(lang.GetMessage("Clear history", this, player.Id), phone.GetIdentity()));
                    break;
                case "trackers":
                    phoneManager.ClearTrackers(phone);
                    if (!phoneManager.IsStateEqualTo(entity, 0))
                        ShowPhoneUI(entity, phone);
                    else
                        player.Reply(string.Format(lang.GetMessage("Clear trackers", this, player.Id), phone.GetIdentity()));
                    break;
                default:
                    break;
            }
        }

        [Command("phone.uiclose"), Permission(PermissionTemp)]
        private void cmd_uiclose(IPlayer player, string command, string[] args)
        {
            HideAllUI(BasePlayer.FindByID(ulong.Parse(player.Id)));
            string usage = string.Format(lang.GetMessage("Usage", this, player.Id), command);
            player.Reply(usage);
        }

        #endregion

        #region Admin Commands
        [Command("phone.history"), Permission(PermissionAdmin)]
        private void cmd_phone_history(IPlayer player, string command, string[] args)
        {
            try
            {
                int phoneNumber = int.Parse(args[0]);
                RegisteredPhone phone = phoneManager.FindPhoneByNumber(phoneNumber);
                if (phone != null)
                {
                    PhoneRecordList records = phoneManager.GetPhoneRecords(phoneNumber);
                    string recordListStr = "<" + phoneNumber + ">\n";
                    foreach (PhoneRecord record in records.RecentRecords(10))
                    {
                        recordListStr += string.Format("({0}, {1}, {2})", record.GetTimeElapsed(), record.status, record.Number(phoneManager)) + "\n";
                    }
                    player.Reply(recordListStr);
                }
            }
            catch (Exception)
            {
                string usage = string.Format(lang.GetMessage("Usage", this, player.Id), command) + " <phone_number>";
                player.Reply(usage);
            }
        }
        #endregion

        #endregion

        #region Custom Hooks
        void UsePhone(BasePlayer player, RegisteredPhone phone)
        {
            if (Interface.CallHook("OnPhoneUse", player, phone.phoneController) != null) return;
            if (player.IsValid() && phone != null && permission.UserHasPermission(player.UserIDString, PermissionUse))
            {
                if (phone.phoneController.activeCallTo == null)
                    ShowPhoneUI(player, phone);
                HideNotificationHUD(player);
                int changedMessages = phoneManager.GetPhoneMessages(phone.GetNumber()).MarkAllAsRead();
                int changedRecords = phoneManager.GetPhoneRecords(phone.GetNumber()).MarkAllAsRead();
                foreach (ulong userId in phoneManager.GetPhoneTrackers(phone))
                {
                    BasePlayer tracker = BasePlayer.FindByID(userId);
                    if (tracker.IsValid())
                    {
                        phoneManager.UpdatePhoneMessageCount(tracker.userID, phoneManager.GetPhoneMessageCount(tracker.userID) - changedMessages);
                        phoneManager.UpdatePhoneRecordsCount(tracker.userID, phoneManager.GetPhoneRecordsCount(tracker.userID) - changedRecords);
                        ShowUnreadIndicator(tracker);
                        ShowCallIndicator(tracker);
                    }
                }
            }
        }

        void UsePhoneEnd(BasePlayer player)
        {
            if (Interface.CallHook("OnPhoneUseEnd", player) != null) return;
            HideAllUI(player);
        }

        void ActiveCall(BasePlayer player, RegisteredPhone phone)
        {
            if (Interface.CallHook("OnActiveCall", player, phone.phoneController) != null) return;
            HideAllUI(player);
        }

        void ActiveCallEnd(BasePlayer player, RegisteredPhone phone)
        {
            if (Interface.CallHook("OnActiveCallEnd", player, phone.phoneController) != null) return;
            ShowPhoneUI(player, phone);
        }
        #endregion

        #region Hooks

        void Init()
        {
            #region Unsubscribe
            Unsubscribe(nameof(OnPhoneAnswered));
            Unsubscribe(nameof(OnPhoneDial));
            Unsubscribe(nameof(OnEntitySpawned));
            Unsubscribe(nameof(OnEntityDeath));
            Unsubscribe(nameof(CanPickupEntity));
            Unsubscribe(nameof(OnPlayerConnected));
            Unsubscribe(nameof(OnUserPermissionGranted));
            Unsubscribe(nameof(OnPhoneDialFail));
            Unsubscribe(nameof(OnServerSave));
            #endregion

            InitCommands();
        }

        void OnServerInitialized()
        {
            PLUGIN = this;
            try
            {
                ImageLibrary.Call("isLoaded", null);
            }
            catch (Exception)
            {
                PrintWarning($"The required dependency ImageLibrary is not installed, unloading {Name}.");
                Interface.Oxide.UnloadPlugin(Name);
                return;
            }

            #region Subscribe
            Subscribe(nameof(OnPhoneAnswered));
            Subscribe(nameof(OnPhoneDial));
            Subscribe(nameof(OnEntitySpawned));
            Subscribe(nameof(OnEntityDeath));
            Subscribe(nameof(CanPickupEntity));
            Subscribe(nameof(OnPlayerConnected));
            Subscribe(nameof(OnUserPermissionGranted));
            Subscribe(nameof(OnPhoneDialFail));
            Subscribe(nameof(OnServerSave));
            #endregion

            phoneManager = new PhoneManager();

            LoadImages();
            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                HideAllUI(player);
                HideNotificationHUD(player);
                ShowUnreadIndicator(player);
                ShowCallIndicator(player);
                CheckIfUsingPhone(player);
            }
            ResetMessages();
        }

        void OnPhoneAnswered(PhoneController receiverPhone, PhoneController callerPhone)
        {
            phoneManager.RegisterPhone(callerPhone);
            phoneManager.RegisterPhone(receiverPhone);
            phoneManager.GetPhoneRecords(receiverPhone.PhoneNumber).RecordAnswered(receiverPhone, callerPhone, phoneManager);
            HideAllUI(receiverPhone.currentPlayer);
            HideAllUI(callerPhone.currentPlayer);
        }

        object OnPhoneDial(PhoneController callerPhone, PhoneController receiverPhone, BasePlayer player)
        {
            HideAllUI(player);
            phoneManager.RegisterPhone(callerPhone);
            phoneManager.RegisterPhone(receiverPhone);
            phoneManager.GetPhoneRecords(callerPhone.PhoneNumber).RecordOutgoing(callerPhone, receiverPhone, phoneManager);
            if (config.EnableIncomingCallNotifications)
                NotifyIncoming(receiverPhone.baseEntity.net.ID, callerPhone.baseEntity.net.ID);
            return null;
        }

        void OnEntitySpawned(Telephone entity)
        {
            phoneManager.RegisterPhone(entity.Controller);
        }

        void OnEntityDeath(Telephone entity, HitInfo info)
        {
            phoneManager.UnregisterPhone(entity);
        }

        bool CanPickupEntity(BasePlayer player, Telephone entity)
        {
            phoneManager.UnregisterPhone(entity);
            return true;
        }

        void OnPlayerConnected(BasePlayer player)
        {
            InitPlayer(player);
        }

        void OnUserPermissionGranted(string id, string permName)
        {
            if (permName == PermissionUse)
                InitPlayer(BasePlayer.FindByID(ulong.Parse(id)));
        }

        object OnPhoneDialFail(PhoneController callerPhone, Telephone.DialFailReason reason, BasePlayer player)
        {
            if (callerPhone == null) return null;
            PhoneController receiverPhone = callerPhone.activeCallTo;
            if (receiverPhone == null) return null;
            phoneManager.RegisterPhone(callerPhone);
            phoneManager.RegisterPhone(receiverPhone);

            if (reason == Telephone.DialFailReason.SelfHangUp || reason == Telephone.DialFailReason.TimedOut)
            {
                phoneManager.GetPhoneRecords(receiverPhone.PhoneNumber).RecordMissed(receiverPhone, callerPhone, phoneManager);
                if (player != null && callerPhone != null)
                {
                    ShowPhoneUI(player, phoneManager.FindPhoneByNumber(callerPhone.PhoneNumber));
                    timer.In(0.05f, () =>
                    {
                        if (receiverPhone != null)
                            receiverPhone.activeCallTo = null;
                        if (!phoneManager.ExceededMessageLimit(player.userID) && !receiverPhone.currentPlayer.IsValid())
                            ShowInputUI(player, callerPhone.PhoneNumber, receiverPhone.PhoneNumber);
                    });
                    

                }
            }

            return null;
        }

        void OnServerSave()
        {
            phoneManager.SavePhoneMessages();
            phoneManager.SavePhoneRecords();
            phoneManager.SavePreferences();
            phoneManager.SaveTrackedPhones();
            Puts("saved data");
        }

        #endregion

        #region Helpers
        private string FormatTxt(string text, string color = "white", string size = "14")
        {
            return $"<size={size}>[#{color}]{text}[/#]</size>";
        }

        private void LoadImages()
        {
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/P4yACUv.png", "PhonesPlusIcon", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/HlSs8oN.png", "CallIcon", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/wbEpjW2.png", "HistoryIcon", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/dpAt1K4.png", "MessageIcon", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/CXcaqw7.png", "CloseIcon", 0UL);
        }

        private void CheckIfUsingPhone(BasePlayer player)
        {
            if (player.IsValid() && player.IsConnected)
            {
                if (player.HasActiveTelephone && phoneManager.IsStateEqualTo(player, 0))
                {
                    RegisteredPhone phone = phoneManager.GetNearbyPhone(player);
                    if (phone != null)
                    {
                        phoneManager.SetState(player, 1);
                        UsePhone(player, phone);
                    }
                }
                else if (player.HasActiveTelephone && phoneManager.IsStateEqualTo(player, 1))
                {
                    RegisteredPhone phone = phoneManager.GetNearbyPhone(player);
                    if (phone != null)
                    {
                        if (phone.phoneController.activeCallTo != null)
                        {
                            phoneManager.SetState(player, 2);
                            ActiveCall(player, phone);
                        }
                    }
                }
                else if (player.HasActiveTelephone && phoneManager.IsStateEqualTo(player, 2))
                {
                    RegisteredPhone phone = phoneManager.GetNearbyPhone(player);
                    if (phone != null)
                    {
                        if (phone.phoneController.activeCallTo == null)
                        {
                            phoneManager.SetState(player, 1);
                            ActiveCallEnd(player, phone);
                        }
                    }
                }
                else if (!player.HasActiveTelephone && !phoneManager.IsStateEqualTo(player, 0))
                {
                    phoneManager.SetState(player, 0);
                    UsePhoneEnd(player);
                }

                timer.In(0.05f, () =>
                {
                    CheckIfUsingPhone(player);
                });

            }
        }

        private void ResetMessages()
        {
            timer.In(3600f, () =>
            {
                phoneManager.ResetHourlyMessageLimits();
                ResetMessages();
            });
        }

        private void InitPlayer(BasePlayer player)
        {
            if (player.IsValid())
            {
                HideAllUI(player);
                CheckIfUsingPhone(player);
                ShowUnreadIndicator(player);
                ShowCallIndicator(player);
            }
        }

        private string ElapsedTimeString(BasePlayer player, long seconds)
        {
            if (seconds < 3600)
                return string.Format(lang.GetMessage("Time minutes", this, player.UserIDString), Math.Max(1, Math.Round((double)seconds / 60)));
            if (seconds < 86400)
                return string.Format(lang.GetMessage("Time hours", this, player.UserIDString), Math.Max(1, Math.Round((double)seconds / 3600)));
            else
                return string.Format(lang.GetMessage("Time hours", this, player.UserIDString), Math.Max(1, Math.Round((double)seconds / 86400)));
        }

        void NotifyIncoming(uint receiverPhoneID, uint callerPhoneID)
        {
            RegisteredPhone receivingPhone = phoneManager.FindPhoneByID(receiverPhoneID);
            RegisteredPhone callingPhone = phoneManager.FindPhoneByID(callerPhoneID);
            List<ulong> trackers = phoneManager.GetPhoneTrackers(receivingPhone);
            foreach (ulong userId in trackers)
            {
                BasePlayer tracker = BasePlayer.FindByID(userId);
                if (tracker.IsValid())
                {
                    if (phoneManager.GetPreference<bool>(tracker.userID, "notifications") && phoneManager.IsStateEqualTo(tracker, 0))
                    {
                        string message = string.Format(lang.GetMessage("HUD incoming", this, tracker.UserIDString), callingPhone.GetIdentity());
                        ShowNotificationHUD(tracker, message, receivingPhone);
                    };
                }
            }
        }
        #endregion

        #region Classes

        class PhoneMessage
        {
            public readonly int senderNumber;
            public readonly int receiverNumber;
            public readonly string text;
            public bool unread;
            public long time;

            public PhoneMessage(int senderNumber, int receiverNumber, string text, long time = 0)
            {
                this.text = text;
                this.senderNumber = senderNumber;
                this.receiverNumber = receiverNumber;
                if (time == 0)
                    this.time = DateTimeOffset.Now.ToUnixTimeSeconds();
                else
                    this.time = time;
                this.unread = true;
            }

            public long GetTimeElapsed()
            {
                return DateTimeOffset.Now.ToUnixTimeSeconds() - time;
            }

            public string SenderID(PhoneManager manager)
            {
                RegisteredPhone phone = manager.FindPhoneByNumber(senderNumber);
                return phone != null ? phone.GetIdentity() : manager.UNREGISTERED;
            }

            public string ReceiverID(PhoneManager manager)
            {
                RegisteredPhone phone = manager.FindPhoneByNumber(receiverNumber);
                return phone != null ? phone.GetIdentity() : manager.UNREGISTERED;
            }
        }

        class PhoneMessageList
        {
            public List<PhoneMessage> messages;

            public PhoneMessageList()
            {
                messages = new List<PhoneMessage>();
            }

            public List<PhoneMessage> RecentMessages(int amount)
            {
                List<PhoneMessage> recent = new List<PhoneMessage>();
                for (int i = Math.Max(0, messages.Count - amount); i < messages.Count; ++i)
                {
                    recent.Add(messages[i]);
                }
                recent.Sort((x, y) => y.time.CompareTo(x.time));
                return recent;
            }

            public int MarkAllAsRead()
            {
                int changed = 0;
                foreach (PhoneMessage message in messages)
                {
                    if (message.unread)
                    {
                        changed++;
                        message.unread = false;
                    }
                }
                return changed;
            }
        }

        class PhoneRecord
        {
            public readonly int callerNumber;
            public readonly int receiverNumber;
            public bool unread;
            public readonly string status; /* answered, missed, outgoing */
            public long time;

            public PhoneRecord(string status, int callerNumber, int receiverNumber, long time = 0)
            {
                this.status = status;
                this.callerNumber = callerNumber;
                this.receiverNumber = receiverNumber;
                if (time == 0)
                    this.time = DateTimeOffset.Now.ToUnixTimeSeconds();
                else
                    this.time = time;
                this.unread = true;
            }

            public long GetTimeElapsed()
            {
                return DateTimeOffset.Now.ToUnixTimeSeconds() - time;
            }

            public string CallerID(PhoneManager manager)
            {
                RegisteredPhone phone = manager.FindPhoneByNumber(callerNumber);
                if (phone != null)
                    return phone.GetIdentity();
                return manager.UNREGISTERED;
            }

            public string ReceiverID(PhoneManager manager)
            {
                RegisteredPhone phone = manager.FindPhoneByNumber(receiverNumber);
                if (phone != null)
                    return phone.GetIdentity();
                return manager.UNREGISTERED;
            }

            public string ID(PhoneManager manager)
            {
                if (status == "outgoing")
                    return ReceiverID(manager);
                return CallerID(manager);
            }

            public int Number(PhoneManager manager)
            {
                if (status == "outgoing")
                    return receiverNumber;
                return callerNumber;
            }
        }

        class PhoneRecordList
        {
            public List<PhoneRecord> records;

            [NonSerialized]
            public PhoneController phoneItem;

            public PhoneRecordList(PhoneController phone)
            {
                records = new List<PhoneRecord>();
                phoneItem = phone;
            }

            public PhoneRecordList()
            {
                records = new List<PhoneRecord>();
            }

            public List<PhoneRecord> RecentRecords(int amount)
            {
                List<PhoneRecord> recent = new List<PhoneRecord>();
                for (int i = Math.Max(0, records.Count - amount); i < records.Count; ++i)
                {
                    recent.Add(records[i]);
                }
                recent.Sort((x, y) => y.time.CompareTo(x.time));
                return recent;
            }

            public void RecordAnswered(PhoneController thisPhone, PhoneController callerPhone, PhoneManager manager)
            {
                records.Add(new PhoneRecord("answered", callerPhone.PhoneNumber, thisPhone.PhoneNumber));
            }

            public void RecordMissed(PhoneController thisPhone, PhoneController callerPhone, PhoneManager manager)
            {
                RegisteredPhone phone = manager.FindPhoneByNumber(thisPhone.PhoneNumber);
                records.Add(new PhoneRecord("missed", callerPhone.PhoneNumber, thisPhone.PhoneNumber));
                foreach (ulong userId in manager.GetPhoneTrackers(phone))
                {
                    BasePlayer tracker = BasePlayer.FindByID(userId);
                    if (tracker.IsValid())
                    {
                        manager.UpdatePhoneRecordsCount(tracker.userID, manager.GetPhoneRecordsCount(tracker.userID) + 1);
                        PLUGIN.ShowCallIndicator(tracker);
                    }
                }
            }

            public void RecordOutgoing(PhoneController thisPhone, PhoneController receiverPhone, PhoneManager manager)
            {
                records.Add(new PhoneRecord("outgoing", thisPhone.PhoneNumber, receiverPhone.PhoneNumber));
            }

            public int MarkAllAsRead()
            {
                int changed = 0;
                foreach (PhoneRecord record in records)
                {
                    if (record.unread)
                    {
                        changed++;
                        record.unread = false;
                    }
                }
                return changed;
            }
        }

        class RegisteredPhone
        {
            public readonly BaseEntity baseEntity;

            public readonly PhoneController phoneController;

            public RegisteredPhone(PhoneController phoneController)
            {
                this.phoneController = phoneController;
                this.baseEntity = phoneController.baseEntity;
            }

            public uint GetID()
            {
                return baseEntity.net.ID;
            }

            public int GetNumber()
            {
                return phoneController.PhoneNumber;
            }

            public string GetName()
            {
                return phoneController.PhoneName;
            }

            public bool HasName()
            {
                return phoneController.PhoneName != null && phoneController.PhoneName != "";
            }

            public string GetIdentity()
            {
                if (HasName())
                    return GetName().Substring(0, Math.Min(16, GetName().Length));
                return GetNumber().ToString();
            }

            public bool UserHasAuth(BasePlayer player)
            {
                BuildingPrivlidge priv = baseEntity.GetBuildingPrivilege();
                if (priv != null)
                {
                    foreach (ProtoBuf.PlayerNameID playerID in priv.authorizedPlayers)
                    {
                        if (playerID.userid == player.userID)
                            return true;
                    }
                }
                return false;
            }
        }

        class PhoneManager
        {
            public List<uint> registeredPhoneIds;
            public List<RegisteredPhone> registeredPhones;
            private Dictionary<uint, RegisteredPhone> id2phone;
            private Dictionary<int, RegisteredPhone> number2phone;
            private Dictionary<ulong, List<uint>> userTrackedPhones;
            private Dictionary<uint, List<ulong>> trackersOfPhone;
            private Dictionary<ulong, Dictionary<string, object>> userPreferences;
            public Dictionary<int, PhoneRecordList> phoneRecords;
            private Dictionary<ulong, int> phoneRecordsCount;
            public Dictionary<int, PhoneMessageList> phoneMessages;
            private Dictionary<ulong, int> phoneMessageCount;
            private Dictionary<ulong, int> hourlyMessageCount;
            private Dictionary<ulong, int> callState;

            public readonly string UNREGISTERED = "???";

            public PhoneManager()
            {
                registeredPhones = new List<RegisteredPhone>();
                registeredPhoneIds = new List<uint>();
                id2phone = new Dictionary<uint, RegisteredPhone>();
                number2phone = new Dictionary<int, RegisteredPhone>();
                userTrackedPhones = new Dictionary<ulong, List<uint>>();
                trackersOfPhone = new Dictionary<uint, List<ulong>>();
                userPreferences = new Dictionary<ulong, Dictionary<string, object>>();
                phoneRecords = new Dictionary<int, PhoneRecordList>();
                phoneRecordsCount = new Dictionary<ulong, int>();
                phoneMessages = new Dictionary<int, PhoneMessageList>();
                phoneMessageCount = new Dictionary<ulong, int>();
                hourlyMessageCount = new Dictionary<ulong, int>();
                callState = new Dictionary<ulong, int>();
                RegisterExistingPhones();
                LoadTrackedPhones();
                LoadPhoneRecords();
                LoadPhoneMessages();
                LoadPreferences();
            }

            public void LeaveMessage(int senderNumber, int targetNumber, string text)
            {
                RegisteredPhone phone = FindPhoneByNumber(targetNumber);
                if (phone != null)
                {
                    if (!phoneMessages.ContainsKey(targetNumber))
                        phoneMessages.Add(targetNumber, new PhoneMessageList());
                    phoneMessages[targetNumber].messages.Add(new PhoneMessage(senderNumber, targetNumber, text));
                    foreach (ulong userId in GetPhoneTrackers(phone))
                    {
                        BasePlayer tracker = BasePlayer.FindByID(userId);
                        if (tracker.IsValid())
                        {
                            UpdatePhoneMessageCount(tracker.userID, GetPhoneMessageCount(tracker.userID) + 1);
                            PLUGIN.ShowUnreadIndicator(tracker);
                        }
                    }
                }
            }

            public void InitPreferences(ulong userID)
            {
                if (!userPreferences.ContainsKey(userID))
                {
                    userPreferences.Add(userID, new Dictionary<string, object>() {
                        { "notifications", true },
                        { "indicators", true }
                    });
                }
            }

            public void SetPreference(ulong userID, string key, object value)
            {
                InitPreferences(userID);
                userPreferences[userID][key] = value;
            }

            public T GetPreference<T>(ulong userID, string key)
            {
                InitPreferences(userID);
                return (T)userPreferences[userID][key];
            }

            public void RegisterPhone(PhoneController phone)
            {
                if (!registeredPhoneIds.Contains(phone.baseEntity.net.ID))
                {
                    RegisteredPhone newPhone = new RegisteredPhone(phone);
                    id2phone.Add(newPhone.GetID(), newPhone);
                    number2phone.Add(newPhone.GetNumber(), newPhone);
                    registeredPhones.Add(newPhone);
                    registeredPhoneIds.Add(newPhone.GetID());
                    phoneRecords.Add(newPhone.GetNumber(), new PhoneRecordList());
                    phoneMessages.Add(newPhone.GetNumber(), new PhoneMessageList());
                }
            }

            public void UnregisterPhone(Telephone baseEntity)
            {
                if (baseEntity.IsValid() && registeredPhoneIds.Contains(baseEntity.net.ID))
                {
                    RegisteredPhone phone = id2phone[baseEntity.net.ID];
                    id2phone.Remove(phone.GetID());
                    number2phone.Remove(phone.GetNumber());
                    foreach (ulong userId in GetPhoneTrackers(phone))
                    {
                        BasePlayer player = BasePlayer.FindByID(userId);
                        if (player.IsValid())
                        {
                            int changedMessages = GetPhoneMessages(phone.GetNumber()).MarkAllAsRead();
                            int changedRecords = GetPhoneRecords(phone.GetNumber()).MarkAllAsRead();
                            UpdatePhoneMessageCount(player.userID, GetPhoneMessageCount(player.userID) - changedMessages);
                            UpdatePhoneRecordsCount(player.userID, GetPhoneRecordsCount(player.userID) - changedRecords);
                            PLUGIN.ShowUnreadIndicator(player);
                            PLUGIN.ShowCallIndicator(player);
                            userTrackedPhones[player.userID].Remove(phone.GetID());
                        }

                    }

                    if (trackersOfPhone.ContainsKey(phone.GetID()))
                        trackersOfPhone.Remove(phone.GetID());
                    registeredPhones.Remove(phone);
                    registeredPhoneIds.Remove(phone.GetID());
                    phoneRecords.Remove(phone.GetNumber());
                    phoneMessages.Remove(phone.GetNumber());

                }
            }

            public bool TrackPhone(BasePlayer player, int phoneNumber)
            {
                RegisteredPhone phone = FindPhoneByNumber(phoneNumber);

                if (phone != null && player.IsValid())
                {
                    if (!userTrackedPhones.ContainsKey(player.userID))
                        userTrackedPhones.Add(player.userID, new List<uint>());
                    if (!trackersOfPhone.ContainsKey(phone.GetID()))
                        trackersOfPhone.Add(phone.GetID(), new List<ulong>());

                    userTrackedPhones[player.userID].Add(phone.GetID());
                    trackersOfPhone[phone.GetID()].Add(player.userID);

                    return true;
                }
                /* Phone not registered */
                return false;
            }

            public bool UntrackPhone(BasePlayer player, int phoneNumber)
            {
                RegisteredPhone phone = FindPhoneByNumber(phoneNumber);

                if (phone != null)
                {
                    if (this.userTrackedPhones.ContainsKey(player.userID) && this.userTrackedPhones[player.userID].Contains(phone.GetID()))
                    {
                        this.userTrackedPhones[player.userID].Remove(phone.GetID());
                        this.trackersOfPhone[phone.GetID()].Remove(player.userID);
                    }
                    return true;
                }
                return false;
            }

            public void ClearTrackers(RegisteredPhone phone)
            {
                if (phone != null && trackersOfPhone.ContainsKey(phone.GetID()))
                {
                    int changedMessages = GetPhoneMessages(phone.GetNumber()).MarkAllAsRead();
                    int changedRecords = GetPhoneRecords(phone.GetNumbe
// ... [Code preview truncated due to length. Full source in attached file] ...

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