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

FREE ComputersPlus : 1.0.6 1.0.6

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core.Plugins;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Oxide.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using Oxide.Core.Libraries.Covalence;
using UnityEngine;
using System.Text;
using Oxide.Core.Libraries;
using Oxide.Game.Rust.Cui;
using System.Linq;
using System.Text.RegularExpressions;
namespace Oxide.Plugins {
    [Info("Computers Plus", "mr01sam", "1.0.6")]
    [Description("Adds new functionality to the computer stations.")]
    partial class ComputersPlus : CovalencePlugin {
        /*
		 * CHANGELOG
		 * - Fixed bug where players would not get emails if they were offline.* - Added message screen for players without permissions.* - Fixed broken images.*/
        private static ComputersPlus PLUGIN;
        [PluginReference]
        private Plugin ImageLibrary;
        /* Global Data */
        private static Dictionary<string, string> Language = new Dictionary<string, string>();
        private static Dictionary<string, ComputersPlusApp> RegisteredApps = new Dictionary<string, ComputersPlusApp>();
        private static Dictionary<string, string> AppsInUse = new Dictionary<string, string>();
#region Properties
        internal EZUI.Component AppComponent {
            get;
            private set;
        }
        = null;
        private bool Success {
            get;
            set;
        }
        = true;
#endregion
#region Permissions
        private const string PermissionAdmin = "computersplus.admin";
        /* Additional permissions are registered for each App in the format computersplus.<app-name> */
#endregion
#region Initialization
        void CreateApps() {
            if (RegisteredApps == null) {
                RegisteredApps = new Dictionary<string, ComputersPlusApp>();
            }
            RegisterApp(EMAIL_APP);
        }
        void Init() {
            PLUGIN = this;
            UnsubscribeAll();
        }
        void Unload() {
            CleanupUI();
            UnloadApps();
            NullifyStaticVariables();
        }
        void OnServerSave() {
            SaveApps();
        }
        void OnServerInitialized(bool initial) {
            try {
                ImageLibrary.Call("isLoaded", null);
            }
            catch (Exception) {
                PrintWarning($"The required dependency ImageLibary is not installed, {Name} will not work properly without it.");
                Success = false;
                return;
            }
            EZUI.GenerateToken();
            LoadImages();
            InitApps();
            SubscribeAll();
        }
        void UnsubscribeAll() {
            Unsubscribe(nameof(OnEntityMounted));
            Unsubscribe(nameof(OnEntityDismounted));
            Unsubscribe(nameof(CanDismountEntity));
            Unsubscribe(nameof(OnBookmarkControl));
            Unsubscribe(nameof(OnBookmarkControlEnd));
        }
        void SubscribeAll() {
            Subscribe(nameof(OnEntityMounted));
            Subscribe(nameof(OnEntityDismounted));
            Subscribe(nameof(CanDismountEntity));
            Subscribe(nameof(OnBookmarkControl));
            Subscribe(nameof(OnBookmarkControlEnd));
        }
        void NullifyStaticVariables() {
            PLUGIN = null;
            RegisteredApps = null;
            AppsInUse = null;
            Language = null;
        }
        void CleanupUI() {
            for (int i = 0; i < BasePlayer.activePlayerList.Count; i++) {
                EZUI.DestroyAll(BasePlayer.activePlayerList[i]);
            }
        }
        void InitApps() {
            foreach(ComputersPlusApp app in RegisteredApps.Values) {
                ImageLibrary.Call<bool>("AddImage", app.IconUrl, $"{app.Id}Icon", 0UL);
                Call(app.InitMethod);
            }
        }
        void SaveApps() {
            foreach (ComputersPlusApp app in RegisteredApps.Values) {
                Call(app.SaveMethod);
            }
        }
        void UnloadApps() {
            foreach (ComputersPlusApp app in RegisteredApps.Values) {
                Call(app.UnloadMethod);
            }
        }
#endregion
#region Oxide Hooks
        void OnEntityMounted(ComputerStation entity, BasePlayer basePlayer) {
            ShowHomeUi(basePlayer);
        }
        void OnEntityDismounted(ComputerStation entity, BasePlayer basePlayer) {
            CloseUi(basePlayer);
            NextTick(() => {
                CloseUi(basePlayer);
                // incase it doesn't close initally
            }
            );
        }
        object CanDismountEntity(BasePlayer player, ComputerStation computerStation) {
            if (IsUsingApp(player)) {
                return false;
            }
            return null;
        }
        object OnBookmarkControl(ComputerStation computerStation, BasePlayer basePlayer, string bookmarkName, IRemoteControllable remoteControllable) {
            CloseUi(basePlayer);
            return null;
        }
        object OnBookmarkControlEnd(ComputerStation computerStation, BasePlayer basePlayer, BaseEntity controlledEntity) {
            ShowHomeUi(basePlayer);
            return null;
        }
#endregion
#region Helper Methods
        void RegisterApp(ComputersPlusApp newApp) {
            RegisteredApps.Add(newApp.Id, newApp);
            if (!permission.PermissionExists(newApp.Permission)) {
                permission.RegisterPermission(newApp.Permission, this);
            }
            Call(newApp.CreateMethod);
        }
        void LoadImages() {
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/43ytxMa.png", $"App.Close", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/oM0NEIP.png", $"PC.Denied", 0UL);
        }
        bool IsUsingComputer(BasePlayer basePlayer) => basePlayer.GetMounted() != null ? (basePlayer.GetMounted() is ComputerStation) : false;
        bool IsUsingApp(BasePlayer player, string appId = null) {
            if (appId != null) return AppsInUse.ContainsKey(player.UserIDString) && AppsInUse[player.UserIDString] == appId;
            return AppsInUse.ContainsKey(player.UserIDString);
        }
        bool UserHasAnyPermission(BasePlayer basePlayer) {
            return RegisteredApps.Values.Any(app => permission.UserHasPermission(basePlayer.UserIDString, app.Permission));
        }
#endregion
#region UI
        private readonly string BASE_UI_ID = "PC";
        private readonly string HOME_UI_ID = "HOME";
        private readonly string APP_UI_ID = "APP";
        void CloseUi(BasePlayer basePlayer) {
            AppsInUse.Remove(basePlayer.UserIDString);
            var ui = EZUI.Find(basePlayer.UserIDString, BASE_UI_ID);
            ui?.Destroy(basePlayer);
        }
        void CloseHomeUi(BasePlayer basePlayer) {
            var ui = EZUI.Find(basePlayer.UserIDString, $"{BASE_UI_ID}.Content.{HOME_UI_ID}");
            ui?.Destroy(basePlayer);
        }
        void CloseAppUi(BasePlayer basePlayer) {
            var ui = EZUI.Find(basePlayer.UserIDString, $"{BASE_UI_ID}.Content.{HOME_UI_ID}.Content.{APP_UI_ID}");
            ui?.Destroy(basePlayer);
            AppsInUse.Remove(basePlayer.UserIDString);
        }
        EZUI.Component CreateAppGrid(EZUI.Component home, BasePlayer basePlayer) {
            var grid = new EZUI.LayoutComponent("Apps") {
                Transparent = true, RowCount = 8, ColCount = 15, PixelPadding = new EZUI.Dir<int>(5)
            }
            .Create(home);
            foreach (ComputersPlusApp app in RegisteredApps.Values) {
                if (app != null && permission.UserHasPermission(basePlayer.UserIDString, app.Permission)) {
                    var box = new EZUI.BoxComponent(app.Id) {
                        Transparent = true
                    }
                    .Create(grid);
                    var icon = new EZUI.ImageComponent("Icon") {
                        ImageKey = $"{app.Id}Icon", Size = 0.6f, AnchorTo = EZUI.Anchor.TopCenter
                    }
                    .Create(box);
                    var text = new EZUI.TextComponent("Title") {
                        Text = app.Name, TextAlign = TextAnchor.UpperCenter, FontSize = 10, PixelHeight = 25, FontColor = EZUI.StyleSheet.DEFAULT.FontColorLight1, AnchorTo = EZUI.Anchor.BottomCenter
                    }
                    .Create(box);
                    var button = new EZUI.ButtonComponent("Click") {
                        Transparent = true, Command = $"app.launch {app.Id}", ClickSfx = SFX_LAUNCH
                    }
                    .Create(box);
                }
            }
            return grid;
        }
        void ShowHomeUi(BasePlayer basePlayer) {
            if (Success) {
                bool hasAccess = UserHasAnyPermission(basePlayer);
                var ui = new EZUI.BoxComponent(BASE_UI_ID) {
                    Height = 0.75f, Centered = true, Width = 0.75f,
                }
                .Create();
                var home = new EZUI.BoxComponent(HOME_UI_ID) {
                    OutlinePixelWeight = 5, BackgroundColor = hasAccess ? EZUI.StyleSheet.DEFAULT.HomeBackgroundColor : EZUI.Color.BLACK, Centered = true
                }
                .Create(ui);
                if (hasAccess) {
                    var version = new EZUI.TextComponent("Version") {
                        AnchorTo = EZUI.Anchor.BottomRight, AutoSizeHeight = true, AutoSizeWidth = true, FontColor = EZUI.Color.WHITE, FontSize = 10, Up = 5, Left = 5, TextAlign = TextAnchor.LowerRight, Text = $"COBALT OS v{Version.Major}.{Version.Minor}.{Version.Patch}"
                    }
                    .Create(home);
                    var grid = CreateAppGrid(home, basePlayer);
                }
                else {
                    var denied = new EZUI.ImageComponent("Deny") {
                        ImageKey = "PC.Denied", ImageColor = EZUI.Color.RED, Size = 0.2f, AnchorTo = EZUI.Anchor.MiddleCenter, Up = 50
                    }
                    .Create(home);
                    var text = new EZUI.TextComponent("Text") {
                        Text = Lang("app.access.denied", basePlayer), FontColor = EZUI.Color.RED, TextAlign = TextAnchor.UpperCenter, FontSize = 28, TopAlign = denied.BottomSide.Pixels, Down = 20, PixelHeight = 100
                    }
                    .Create(home);
                    var reason = new EZUI.TextComponent("Reason") {
                        Text = Lang("app.access.reason", basePlayer), FontColor = EZUI.Color.WHITE, TextAlign = TextAnchor.LowerCenter, AnchorTo = EZUI.Anchor.BottomCenter, FontSize = 12, PixelHeight = 100
                    }
                    .Create(home);
                }
                ui.Render(basePlayer);
            }
        }
        void ShowAppUi(BasePlayer basePlayer, ComputersPlusApp app) {
            var home = EZUI.Find(basePlayer, $"{BASE_UI_ID}.{HOME_UI_ID}");
            var window = new EZUI.WindowComponent(APP_UI_ID) {
                HeaderText = app.Name, Scale = 0.85f, Centered = true, OnCloseCommand = "app.close"
            }
            .Create(home);
            this.AppComponent = window;
            window.Render(basePlayer);
            if (!AppsInUse.ContainsKey(basePlayer.UserIDString)) {
                AppsInUse.Add(basePlayer.UserIDString, app.Id);
            }
        }
#endregion
#region Commands
        [Command("app.launch")]
        private void cmd_app_launch(IPlayer player, string command, string[] args) {
            BasePlayer basePlayer = player.Object as BasePlayer;
            if (basePlayer != null && IsUsingComputer(basePlayer)) {
                string appId = args[0];
                ComputersPlusApp app = null;
                if (RegisteredApps.TryGetValue(appId, out app) && permission.UserHasPermission(player.Id, app.Permission)) {
                    ShowAppUi(basePlayer, app);
                    Call(app.LaunchMethod, basePlayer.UserIDString);
                }
                else {
                    player.Reply(Lang("app.launch.error", basePlayer));
                }
            }
        }
        [Command("app.close")]
        private void cmd_app_close(IPlayer player, string command, string[] args) {
            BasePlayer basePlayer = player.Object as BasePlayer;
            if (basePlayer != null) {
                CloseAppUi(basePlayer);
            }
        }
        [Command("pc.leave")]
        private void cmd_pc_leave(IPlayer player, string command, string[] args) {
            BasePlayer basePlayer = player.Object as BasePlayer;
            if (basePlayer != null) {
                EZUI.DestroyAll(basePlayer);
                BaseMountable mountable = basePlayer.GetMounted();
                if (mountable != null && mountable is ComputerStation) {
                    mountable.DismountPlayer(basePlayer);
                }
            }
        }
#endregion
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus {
        class ComputersPlusApp {
            private string _id;
            private string _name;
            private string _iconUrl;
            private string _permission;
            public ComputersPlusApp(string id, string name, string iconUrl, string permission) {
                this._id = id;
                this._name = name;
                this._iconUrl = iconUrl;
                this._permission = permission;
            }
            public string Id {
                get {
                    return _id;
                }
            }
            public string Name {
                get {
                    return _name;
                }
            }
            public string IconUrl {
                get {
                    return _iconUrl;
                }
            }
            public string Permission {
                get {
                    return _permission;
                }
            }
            public string LaunchMethod {
                get {
                    return $"Launch{Id.TitleCase()}App";
                }
            }
            public string SaveMethod {
                get {
                    return $"Save{Id.TitleCase()}App";
                }
            }
            public string CreateMethod {
                get {
                    return $"Create{Id.TitleCase()}App";
                }
            }
            public string InitMethod {
                get {
                    return $"Init{Id.TitleCase()}App";
                }
            }
            public string UnloadMethod {
                get {
                    return $"Unload{Id.TitleCase()}App";
                }
            }
            public override string ToString() {
                return Id.ToString();
            }
        }
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        private Configuration config;
        private partial class Configuration {
        }
        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.Default configuration values will be used.It is recommended to backup your current configuration file and remove it to generate a fresh one.");
                LoadDefaultConfig();
            }
            base.SaveConfig();
        }
        protected override void SaveConfig() => Config.WriteObject(config);
        protected override void LoadDefaultConfig() => config = new Configuration();
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus {
        class DoubleDictionary<TkeyA, TkeyB, Tvalue> {
            private Dictionary<TkeyA, Dictionary<TkeyB, Tvalue>> a2b;
            private Dictionary<TkeyB, Dictionary<TkeyA, Tvalue>> b2a;
            public DoubleDictionary() {
                a2b = new Dictionary<TkeyA, Dictionary<TkeyB, Tvalue>>();
                b2a = new Dictionary<TkeyB, Dictionary<TkeyA, Tvalue>>();
            }
            public void Set(TkeyA keyA, TkeyB keyB, Tvalue value) {
                if (!a2b.ContainsKey(keyA)) a2b.Add(keyA, new Dictionary<TkeyB, Tvalue>());
                if (!b2a.ContainsKey(keyB)) b2a.Add(keyB, new Dictionary<TkeyA, Tvalue>());
                if (!a2b[keyA].ContainsKey(keyB)) a2b[keyA].Add(keyB, value);
                else a2b[keyA][keyB] = value;
                if (!b2a[keyB].ContainsKey(keyA)) b2a[keyB].Add(keyA, value);
                else b2a[keyB][keyA] = value;
            }
            public Tvalue Get(TkeyA keyA, TkeyB keyB) {
                if (a2b.ContainsKey(keyA) && a2b[keyA].ContainsKey(keyB)) return a2b[keyA][keyB];
                return default(Tvalue);
            }
            public Dictionary<TkeyB, Tvalue> GetA(TkeyA keyA) {
                if (a2b.ContainsKey(keyA)) return a2b[keyA];
                return new Dictionary<TkeyB, Tvalue>();
            }
            public Dictionary<TkeyA, Tvalue> GetB(TkeyB keyB) {
                if (b2a.ContainsKey(keyB)) return b2a[keyB];
                return new Dictionary<TkeyA, Tvalue>();
            }
            public bool ContainsKey(TkeyA keyA, TkeyB keyB) {
                return a2b.ContainsKey(keyA) && a2b[keyA].ContainsKey(keyB);
            }
            public bool ContainsKey(TkeyA keyA) {
                return a2b.ContainsKey(keyA);
            }
            public void Delete(TkeyA keyA, TkeyB keyB) {
                if (a2b.ContainsKey(keyA) && a2b[keyA].ContainsKey(keyB)) a2b[keyA].Remove(keyB);
                if (b2a.ContainsKey(keyB) && b2a[keyB].ContainsKey(keyA)) b2a[keyB].Remove(keyA);
            }
            public void DeleteA(TkeyA keyA) {
                foreach (TkeyB keyB in b2a.Keys) if (b2a[keyB].ContainsKey(keyA)) b2a[keyB].Remove(keyA);
                if (a2b.ContainsKey(keyA)) a2b.Remove(keyA);
            }
            public void DeleteB(TkeyB keyB) {
                foreach (TkeyA keyA in a2b.Keys) if (a2b[keyA].ContainsKey(keyB)) a2b[keyA].Remove(keyB);
                if (b2a.ContainsKey(keyB)) b2a.Remove(keyB);
            }
            public int Count(TkeyA keyA) {
                return a2b[keyA].Count;
            }
        }
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        protected override void LoadDefaultMessages() {
            Language = new Dictionary<string, string>();
            CreateApps();
            Language = Language.Concat(new Dictionary<string, string> {
                ["app.error.launch"]
                = "That app is not registered or this player does not have permission to use it.", ["app.access.denied"] = "Access Denied", ["app.access.reason"] = "You do not have any app permissions for this plugin."
            }
            ).ToDictionary(x => x.Key, y => y.Value);
            lang.RegisterMessages(Language, this);
        }
        private string Lang(string key, string id, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
        private string Lang(string key, BasePlayer basePlayer, params object[] args) => string.Format(lang.GetMessage(key, this, basePlayer?.UserIDString), args);
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        public static readonly string SFX_LAUNCH = "assets/prefabs/tools/binoculars/sound/fovchange.prefab";
        public static readonly string SFX_CLICK = "assets/prefabs/tools/detonator/effects/unpress.prefab";
        public static readonly string SFX_SUBMIT = "assets/prefabs/tools/flashlight/effects/turn_on.prefab";
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus {
        private T LoadDataFile<T>(string fileName) {
            try {
                return Interface.Oxide.DataFileSystem.ReadObject<T>($"{Name}/{fileName}");
            }
            catch (Exception) {
                return default(T);
            }
        }
        private void SaveDataFile<T>(string fileName, T data) {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/{fileName}", data);
        }
        private void PlaySfx(BasePlayer player, string sound) => EffectNetwork.Send(new Effect(sound, player, 0, Vector3.zero, Vector3.forward), player.net.connection);
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        private readonly ComputersPlusApp EMAIL_APP = new ComputersPlusApp("email", "Email", "https://freeiconshop.com/wp-content/uploads/edd/mail-var-outline-filled.png", "computersplus.email");
#region App Hooks
        void CreateEmailApp(string userIdString) {
            RegisterEmailLanguage();
        }
        void InitEmailApp() {
            EmailManager.MaxInboxSize = config.Email.MaxInboxSize;
            LoadEmails();
            AddEmailAppImages();
            RegisterEmailFunctions();
        }
        void LaunchEmailApp(string userIdString) {
            BasePlayer basePlayer = BasePlayer.FindByID(ulong.Parse(userIdString));
            RenderEmailApp(basePlayer);
        }
        void SaveEmailApp() {
            SaveEmails();
        }
        void UnloadEmailApp() {
            SaveEmails();
        }
#endregion
#region Config
        private partial class Configuration {
            [JsonProperty(PropertyName = "Email Config")]
            public EmailConfiguration Email = new EmailConfiguration();
        }
        private class EmailConfiguration {
            [JsonProperty(PropertyName = "Max Inbox Size")]
            public int MaxInboxSize {
                get;
                set;
            }
            = 24;
        }
#endregion
#region Helper Methods
        private void AddEmailAppImages() {
            ImageLibrary.Call<bool>("AddImage", "https://freeiconshop.com/wp-content/uploads/edd/mail-var-outline-filled.png", $"{EMAIL_APP.Id}Unread", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://imgur.com/GYiA73s.png", $"{EMAIL_APP.Id}Read", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://imgur.com/dUlC5Yf.png", $"{EMAIL_APP.Id}Compose", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://i.imgur.com/HMcxb5Q.png", $"{EMAIL_APP.Id}Delete", 0UL);
            ImageLibrary.Call<bool>("AddImage", "https://uxwing.com/wp-content/themes/uxwing/download/communication-chat-call/send-icon.png", $"{EMAIL_APP.Id}Send", 0UL);
        }
        private void RegisterEmailLanguage() {
            Language = Language.Concat(new Dictionary<string, string> {
                ["email.compose"]
                = "Compose", ["email.subject"] = "Subject", ["email.recipients"] = "Recipients", ["email.send"] = "Send", ["email.message"] = "Message", ["email.to"] = "To", ["email.from"] = "From", ["email.received"] = "Received", ["email.unread"] = "Unread", ["email.inbox"] = "Inbox", ["email.days"] = "days ago", ["email.hours"] = "hrs ago", ["email.minutes"] = "min ago", ["email.now"] = "just now", ["email.cleared"] = "Cleared inbox for {0}", ["email.success"] = "Successfully sent to {0} recipients", ["email.partial"] = "Successfully sent to {0} recipients.Failed to find {1} recipients.", ["email.fail"] = "Failed to find any recipients.No messages sent.", ["email.usage.clear"] = "Usage: email.clear <username>"
            }
            ).ToDictionary(x => x.Key, x => x.Value);
        }
        private void RegisterEmailFunctions() {
            EZUI.RegisterFunction(nameof(RenderEmailView));
            EZUI.RegisterFunction(nameof(RenderEmailCompose));
            EZUI.RegisterFunction(nameof(SendEmail));
            EZUI.RegisterFunction(nameof(DeleteEmail));
        }
        private void LoadEmails() {
            var existing = LoadDataFile<Dictionary<string, List<EmailMessage>>>("Emails");
            if (existing != null) {
                EmailManager.SetAllEmails(existing);
            }
        }
        private void SaveEmails() {
            var all = EmailManager.GetAllEmails();
            SaveDataFile("Emails", all);
        }
        private void DeleteEmail(string userIdString, string emailGuid) {
            BasePlayer basePlayer = BasePlayer.FindAwakeOrSleeping(userIdString);
            if (basePlayer != null) {
                EmailManager.DeleteEmail(userIdString, Guid.Parse(emailGuid));
                var inbox = UpdateInbox(basePlayer);
                inbox.Paginator?.UpdatePageAndRender(basePlayer);
            }
        }
        private void SendEmail(string userIdString) {
            BasePlayer basePlayer = BasePlayer.FindAwakeOrSleeping(userIdString);
            var recipients = EZUI.Get(basePlayer, EMAIL_APP, "Recipients")?.As<EZUI.InputComponent>()?.Data;
            var subject = EZUI.Get(basePlayer, EMAIL_APP, "Subject")?.As<EZUI.InputComponent>()?.Data;
            var text = EZUI.Get(basePlayer, EMAIL_APP, "Message")?.As<EZUI.InputComponent>()?.Data;
            var split = recipients.Split(',').Select(x => x.Trim()).Where(x => x.Length > 0).Distinct().ToList();
            var recipientIds = split.Select(y => players.FindPlayer(y)?.Id).Distinct().Where(x => !string.IsNullOrEmpty(x)).ToList();
            if (recipients != null && subject != null && text != null) {
                int count = 0;
                if (split.Count > 0) {
                    foreach (var id in recipientIds) {
                        var email = new EmailMessage(userIdString, id, subject, text);
                        EmailManager.SendEmail(email);
                        count++;
                    }
                }
                else {
                    UpdateInfoText(basePlayer, Lang("email.fail", basePlayer));
                }
                string status;
                if (count == split.Count) {
                    status = Lang("email.success", basePlayer, count);
                }
                else if (count > 0) {
                    int fails = split.Count - count;
                    status = Lang("email.partial", basePlayer, count, fails);
                }
                else {
                    status = Lang("email.fail", basePlayer, count);
                }
                var window = EZUI.Get(basePlayer, EMAIL_APP, "Compose");
                if (window != null) {
                    window.Destroy(basePlayer);
                    timer.In(0.5f, () => {
                        UpdateInfoText(basePlayer, status);
                        timer.In(4f, () => {
                            UpdateInfoText(basePlayer, string.Empty);
                        }
                        );
                    }
                    );
                }
                UpdateInbox(basePlayer).Render(basePlayer);
            }
        }
#endregion
#region UI
        private void RenderEmailCompose(string userIdString) {
            var basePlayer = BasePlayer.FindByID(ulong.Parse(userIdString));
            if (basePlayer != null) {
                var height = 45;
                var width = 0.5f;
                var window = new EZUI.WindowComponent("Compose") {
                    HeaderText = Lang("email.compose", basePlayer), Scale = 0.5f
                }
                .Tag(EMAIL_APP).Create();
                var subject = new EZUI.InputComponent("Subject") {
                    Text = $"{Lang("email.subject", basePlayer)}:", CharsLimit = 55, AnchorTo = EZUI.Anchor.TopLeft, PixelMargin = new EZUI.Dir<int>(0, 0, 10, 0), PixelHeight = height, Width = width
                }
                .Tag(EMAIL_APP).Create(window);
                var recipients = new EZUI.InputComponent("Recipients") {
                    Text = $"{Lang("email.recipients", basePlayer)}:", CharsLimit = 1024, TopAlign = subject.BottomSide.Pixels, PixelMargin = new EZUI.Dir<int>(0, 0, 10, 0), PixelHeight = height, Width = width
                }
                .Tag(EMAIL_APP).Create(window);
                var send = new EZUI.ButtonComponent("Send") {
                    Text = Lang("email.send", basePlayer), AnchorTo = EZUI.Anchor.BottomRight, TextAlign = TextAnchor.MiddleCenter, BackgroundColor = EZUI.StyleSheet.DEFAULT.BackgroundColorDark1, OutlineColor = EZUI.StyleSheet.DEFAULT.BackgroundColorLight1, OutlinePixelWeight = 1, PixelWidth = 75, PixelHeight = 25, ClickSfx = SFX_SUBMIT, Command = $"ezui.call {EZUI.Token} SendEmail {basePlayer.UserIDString}", PixelMargin = new EZUI.Dir<int>(5, 0, 0, 0)
                }
                .Create(window);
                var message = new EZUI.InputComponent("Message") {
                    Text = $"{Lang("email.message", basePlayer)}:", CharsLimit = 2048, TextAlign = TextAnchor.UpperLeft, TopAlign = recipients.BottomSide.Pixels, BottomAlign = send.TopSide.Pixels
                }
                .Tag(EMAIL_APP).Create(window);
                window.Render(basePlayer);
            }
        }
        private void RenderEmailView(string userIdString, string emailGuid) {
            var basePlayer = BasePlayer.FindByID(ulong.Parse(userIdString));
            if (basePlayer != null) {
                var email = EmailManager.GetEmail(userIdString, Guid.Parse(emailGuid));
                email.MarkAsRead();
                UpdateInbox(basePlayer).Render(basePlayer);
                var window = new EZUI.WindowComponent("View") {
                    HeaderText = email.Subject, Scale = 0.5f,
                }
                .Create();
                var height = 20;
                var width = 100;
                var to = new EZUI.LayoutComponent("To") {
                    AnchorTo = EZUI.Anchor.TopLeft, PixelHeight = height, PixelWidth = width, ColCount = 2, Entries = new List<EZUI.Component>() {
                        new EZUI.TextComponent("Label") {
                            Text = $"{Lang("email.to", basePlayer)}:"
                        }
                        , new EZUI.TextComponent("Value") {
                            Text = $"{email.RecipientDisplayName}"
                        }
                        ,
                    }
                }
                .Create(window);
                var from = new EZUI.LayoutComponent("From") {
                    TopAlign = to.BottomSide.Pixels, PixelHeight = height, PixelWidth = width, ColCount = 2, Entries = new List<EZUI.Component>() {
                        new EZUI.TextComponent("Label") {
                            Text = $"{Lang("email.from", basePlayer)}:"
                        }
                        , new EZUI.TextComponent("Value") {
                            Text = $"{email.ComposerDisplayName}"
                        }
                        ,
                    }
                }
                .Create(window);
                var received = new EZUI.LayoutComponent("Received") {
                    TopAlign = from.BottomSide.Pixels, PixelHeight = height, PixelWidth = width, ColCount = 2, Entries = new List<EZUI.Component>() {
                        new EZUI.TextComponent("Label") {
                            Text = $"{Lang("email.received", basePlayer)}:"
                        }
                        , new EZUI.TextComponent("Value") {
                            Text = $"{email.ElapsedTimeString(basePlayer)}"
                        }
                        ,
                    }
                }
                .Create(window);
                var subject = new EZUI.LayoutComponent("Subject") {
                    TopAlign = received.BottomSide.Pixels, PixelHeight = height, PixelWidth = width, ColCount = 2, PixelMargin = new EZUI.Dir<int>(0, 0, 5, 0), Entries = new List<EZUI.Component>() {
                        new EZUI.TextComponent("Label") {
                            Text = $"{Lang("email.subject", basePlayer)}:"
                        }
                        , new EZUI.TextComponent("Value") {
                            Text = $"{email.Subject}"
                        }
                        ,
                    }
                }
                .Create(window);
                var text = new EZUI.TextComponent("Message") {
                    TopAlign = subject.BottomSide.Pixels, TextAlign = TextAnchor.UpperLeft, PixelPadding = new EZUI.Dir<int>(5), Text = email.Text, BackgroundColor = EZUI.Color.WHITE
                }
                .Create(window);
                window.Render(basePlayer);
            }
        }
        private EZUI.Component CreateEmailEntryComponent(BasePlayer basePlayer, EmailMessage email, EZUI.Component list) {
            var box = new EZUI.BoxComponent("Item") {
                BackgroundColor = email.Unread ? EZUI.StyleSheet.DEFAULT.BackgroundColorHighlight1 : EZUI.StyleSheet.DEFAULT.BackgroundColorLight2, PixelPadding = new EZUI.Dir<int>(5),
            }
            .Create(list);
            var img = new EZUI.ImageComponent("Icon") {
                Transparent = true, Height = 0.8f, PixelWidth = 18,  //PixelHeight = 36,
                ImageKey = $"{EMAIL_APP.Id}Unread", ImageHidden = !email.Unread, CenterY = true, AnchorTo = EZUI.Anchor.Left
            }
            .Create(box);
            var from = new EZUI.TextComponent("From") {
                Text = email.ComposerDisplayName, PixelWidth = 100, Right = 100
            }
            .Create(box);
            var subject = new EZUI.TextComponent("Subject") {
                Text = email.Subject, PixelWidth = 250, Right = 250
            }
            .Create(box);
            var received = new EZUI.TextComponent("Received") {
                Text = email.ElapsedTimeString(basePlayer), PixelWidth = 100, Right = 550
            }
            .Create(box);
            var btn = new EZUI.ButtonComponent("Clickable") {
                Transparent = true, Command = $"ezui.call {EZUI.Token} RenderEmailView {basePlayer.UserIDString} {email.Guid}", Width = 0.97f
            }
            .Create(box);
            var delete = new EZUI.ButtonComponent("Delete") {
                Transparent = true, ImageKey = $"{EMAIL_APP.Id}Delete", Command = $"ezui.call {EZUI.Token} DeleteEmail {basePlayer.UserIDString} {email.Guid}", Size = 0.5f, CenterY = true, AnchorTo = EZUI.Anchor.MiddleRight, Left = 5
            }
            .Create(box);
            return box;
        }
        EZUI.LayoutComponent UpdateInbox(BasePlayer basePlayer, EZUI.Component inbox = null) {
            if (inbox == null) {
                inbox = EZUI.Get(basePlayer, EMAIL_APP, "Inbox");
            }
            var layout = inbox.As<EZUI.LayoutComponent>();
            layout.ClearEntries();
            var emails = EmailManager.GetPlayerInbox(basePlayer.UserIDString);
            foreach (var email in emails) {
                var entry = CreateEmailEntryComponent(basePlayer, email, layout);
            }
            UpdateStatusText(basePlayer);
            return layout;
        }
        private string StatusText(BasePlayer basePlayer) {
            return $"{Lang("email.inbox", basePlayer)} ({EmailManager.GetPlayerInboxCount(basePlayer.UserIDString)}/{EmailManager.MaxInboxSize})";
        }
        void UpdateStatusText(BasePlayer basePlayer) {
            var status = EZUI.Get(basePlayer, EMAIL_APP, "Status")?.As<EZUI.TextComponent>();
            if (status != null) {
                status.Text = StatusText(basePlayer);
                status.Create().Render(basePlayer);
            }
        }
        void UpdateInfoText(BasePlayer basePlayer, string newText) {
            var info = EZUI.Get(basePlayer, EMAIL_APP, "Info")?.As<EZUI.TextComponent>();
            if (info != null) {
                info.Text = newText;
                info.Create().Render(basePlayer);
            }
        }
        void RenderEmailApp(BasePlayer basePlayer) {
            var main = new EZUI.BoxComponent("Container") {
                Transparent = true
            }
            .Tag(EMAIL_APP.Id).Create(AppComponent);
            var button = new EZUI.ButtonComponent("Compose") {
                Text = $"{Lang("email.compose", basePlayer)}", PixelHeight = 15, PixelWidth = 70, TextAlign = TextAnchor.MiddleCenter, AnchorTo = EZUI.Anchor.TopLeft, BackgroundColor = EZUI.StyleSheet.DEFAULT.BackgroundColorDark1, Command = $"ezui.call {EZUI.Token} RenderEmailCompose {basePlayer.UserIDString}", PixelMargin = new EZUI.Dir<int>(0, 0, 5, 0), OutlinePixelWeight = 1
            }
            .Create(main);
            var header = new EZUI.BoxComponent("Header") {
                PixelHeight = 30, TopAlign = button.BottomSide.Pixels, PixelPadding = new EZUI.Dir<int>(5), PixelMargin = new EZUI.Dir<int>(0, 0, 5, 0)
            }
            .Create(main);
            var h1 = new EZUI.TextComponent("H1") {
                Text = $"{Lang("email.unread", basePlayer)}", AutoSizeWidth = true, Right = 0
            }
            .Create(header);
            var h2 = new EZUI.TextComponent("H2") {
                Text = $"{Lang("email.from", basePlayer)}", AutoSizeWidth = true, Right = 100
            }
            .Create(header);
            var h3 = new EZUI.TextComponent("H3") {
                Text = $"{Lang("email.subject", basePlayer)}", AutoSizeWidth = true, Right = 250
            }
            .Create(header);
            var h4 = new EZUI.TextComponent("H4") {
                Text = $"{Lang("email.received", basePlayer)}", AutoSizeWidth = true, Right = 550
            }
            .Create(header);
            var pag = new EZUI.PaginatorComponent("Paginator") {
                AnchorTo = EZUI.Anchor.BottomLeft, PixelHeight = 25, OutlinePixelWeight = 1, PixelMargin = new EZUI.Dir<int>(5, 0, 0, 0)
            }
            .Create(main).As<EZUI.PaginatorComponent>();
            var body = new EZUI.BoxComponent("Body") {
                TopAlign = header.BottomSide.Pixels, BottomAlign = pag.TopSide.Pixels, OutlinePixelWeight = 1, BackgroundColor = EZUI.Color.WHITE
            }
            .Create(main);
            var status = new EZUI.TextComponent("Status") {
                AnchorTo = EZUI.Anchor.BottomLeft, PixelPadding = new EZUI.Dir<int>(5), FontSize = 10, Text = StatusText(basePlayer), Width = 0.5f, PixelHeight = 25
            }
            .Tag(EMAIL_APP).Create(body);
            var info = new EZUI.TextComponent("Info") {
                AnchorTo = EZUI.Anchor.BottomRight, PixelPadding = new EZUI.Dir<int>(5), FontSize = 10, Text = string.Empty, TextAlign = TextAnchor.MiddleRight, PixelHeight = 25, Width = 0.5f,
            }
            .Tag(EMAIL_APP).Create(body);
            var inbox = new EZUI.LayoutComponent("Inbox") {
                RowCount = 8, ColCount = 1, EntryPixelPadding = new EZUI.Dir<int>(5), BottomAlign = status.TopSide.Pixels
            }
            .Tag(EMAIL_APP.Id).As<EZUI.LayoutComponent>().SetPaginator(pag).Create(body).As<EZUI.LayoutComponent>();
            inbox = UpdateInbox(basePlayer, inbox);
            main.Render(basePlayer);
            pag.UpdatePageAndRender(basePlayer, 1);
        }
#endregion
#region Commands
        [Command("email.clear"), Permission(PermissionAdmin)]
        // email.clear <username>
        private void cmd_email_clear(IPlayer player, string command, string[] args) {
            if (args.Length == 1) {
                var username = args[0];
                var target = players.FindPlayer(username);
                if (target != null) {
                    EmailManager.ClearPlayerInbox(target.Id);
                    player.Reply(Lang("email.cleared", player.Id, target.Name));
                    return;
                }
            }
            player.Reply(Lang("email.usage.clear", player.Id));
        }
#endregion
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus {
        private static class EmailManager {
            private static Dictionary<string, List<EmailMessage>> EmailMessages = new Dictionary<string, List<EmailMessage>>();
            public static int MaxInboxSize {
                get;
                set;
            }
            = 24;
            public static int SendEmail(EmailMessage email) {
                if (EmailMessages.ContainsKey(email.RecipientStringId)) {
                    if (EmailMessages[email.RecipientStringId].Count < MaxInboxSize) {
                        EmailMessages[email.RecipientStringId].Add(email);
                        return 1;
                    }
                }
                else {
                    EmailMessages.Add(email.RecipientStringId, new List<EmailMessage>() {
                        email
                    }
                    );
                    return 1;
                }
                return 0;
            }
            public static void SetAllEmails(Dictionary<string, List<EmailMessage>> emailMessages) {
                EmailMessages = emailMessages;
            }
            public static Dictionary<string, List<EmailMessage>> GetAllEmails() {
                return EmailMessages;
            }
            public static EmailMessage[] GetPlayerInbox(string userIdString) {
                if (EmailMessages.ContainsKey(userIdString)) {
                    return EmailMessages[userIdString].Reverse<EmailMessage>().ToArray();
                }
                else {
                    return new EmailMessage[] {
                    }
                    ;
                }
            }
            public static int GetPlayerInboxCount(string userIdString) {
                if (EmailMessages.ContainsKey(userIdString)) {
                    return EmailMessages[userIdString].Count;
                }
                else {
                    return 0;
                }
            }
            public static void ClearPlayerInbox(string userIdString) {
                if (EmailMessages.ContainsKey(userIdString)) {
                    EmailMessages.Remove(userIdString);
                }
            }
            public static void DeleteEmail(string userIdString, Guid emailGuid) {
                if (EmailMessages.ContainsKey(userIdString)) {
                    EmailMessages[userIdString].RemoveAll(x => x.Guid == emailGuid);
                }
            }
            public static EmailMessage GetEmail(string userIdString, Guid emailGuid) {
                if (EmailMessages.ContainsKey(userIdString)) {
                    return EmailMessages[userIdString].Where(x => x.Guid == emailGuid).FirstOrDefault();
                }
                else {
                    return null;
                }
            }
        }
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        [Serializable]
        private class EmailMessage {
            public EmailMessage(string composerStringId, string recipientStringId, string subject, string text) {
                Guid = Guid.NewGuid();
                Unread = true;
                Subject = subject;
                ComposerStringId = composerStringId;
                RecipientStringId = recipientStringId;
                Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
                Text = text;
            }
            public Guid Guid {
                get;
                set;
            }
            public bool Unread {
                get;
                set;
            }
            public string Subject {
                get;
                set;
            }
            public string ComposerStringId {
                get;
                set;
            }
            public string RecipientStringId {
                get;
                set;
            }
            public long Timestamp {
                get;
                set;
            }
            public string Text {
                get;
                set;
            }
            [JsonIgnore]
            public string ComposerDisplayName {
                get {
                    return BasePlayer.FindAwakeOrSleeping(ComposerStringId)?.displayName;
                }
            }
            [JsonIgnore]
            public string RecipientDisplayName {
                get {
                    return BasePlayer.FindAwakeOrSleeping(RecipientStringId)?.displayName;
                }
            }
            public void MarkAsRead() {
                this.Unread = false;
            }
            public string ElapsedTimeString(BasePlayer basePlayer) {
                var elapsed = TimeSpan.FromSeconds(DateTimeOffset.Now.ToUnixTimeSeconds() - Timestamp);
                if (elapsed.TotalDays >= 1) {
                    return $"{(int)Math.Floor(elapsed.TotalDays)} {PLUGIN.Lang("email.days", basePlayer)}";
                }
                else if (elapsed.TotalHours >= 1) {
                    return $"{(int)Math.Floor(elapsed.TotalHours)} {PLUGIN.Lang("email.hours", basePlayer)}";
                }
                else if (elapsed.TotalMinutes >= 1) {
                    return $"{(int)Math.Floor(elapsed.TotalMinutes)} {PLUGIN.Lang("email.minutes", basePlayer)}";
                }
                else {
                    return $"{PLUGIN.Lang("email.now", basePlayer)}";
                }
            }
        }
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        public static partial class EZUI {
            public class BasicComponent : Component {
                public BasicComponent(string id) : base(id) {
                }
                protected override Component CreateHelper() {
                    return this;
                }
                public override Component Inherit(Component from, bool recursive = false) {
                    this.BackgroundColor = from.BackgroundColor;
                    this.PixelHeight = from.PixelHeight;
                    this.PixelWidth = from.PixelWidth;
                    this.PixelX = from.PixelX;
                    this.PixelY = from.PixelY;
                    this.PixelPadding = from.PixelPadding;
                    this.PixelMargin = from.PixelMargin;
                    return recursive ? base.Inherit(from) : this;
                }
            }
        }
    }
}
namespace Oxide.Plugins {
    partial class ComputersPlus : CovalencePlugin {
        public static partial class EZUI {
            private interface IBoxComponent {
                Color OutlineColor {
                    get;
                    set;
                }
                int OutlinePixelWeight {
                    get;
                    set;
                }
            }
            public class BoxComponent : Component, IBoxComponent {
                public BoxComponent(string id) : base(id) {
                }
                public override Color BackgroundColor {
                    get;
                    set;
                }
                = StyleSheet.DEFAULT.BackgroundColorLight1;
                public Color Outl
// ... [Code preview truncated due to length. Full source in attached file] ...

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