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

FREE StaticTrader : 1.2.3 1.2.3

Нет прав для скачивания
C#:
using Network;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("StaticTrader", "TopPlugin.ru", "1.2.3")]
    [Description("A smart trading system for friends and family.")]
    public class StaticTrader : RustPlugin {
        public const bool Debug = true;
        public static StaticTrader Instance {
            get;
            set;
        }
        public List<Trade> ActiveTrades {
            get;
            set;
        }
        = new List<Trade>();
        public Dictionary<ulong, float> CooledDownPlayers {
            get;
            set;
        }
        = new Dictionary<ulong, float>();
        public Dictionary<ulong, KeyValuePair<string, string>> PlayersSteamInfo {
            get;
            set;
        }
        = new Dictionary<ulong, KeyValuePair<string, string>>();
        public Dictionary<ulong, KeyValuePair<int, string>> PlayerTradeListFilter {
            get;
            set;
        }
        = new Dictionary<ulong, KeyValuePair<int, string>>();
        public Trade GetTrade(BasePlayer sentBy, BasePlayer sentTo) {
            foreach (var x in ActiveTrades) {
                if (x.Target == sentTo && x.Initiator == sentBy) return x;
            }
            return null;
        }
        public Trade GetTrade(BasePlayer sentTo) {
            foreach (var x in ActiveTrades) {
                if (x.Target == sentTo) return x;
            }
            return null;
        }
        public Trade GetTrade(ShopFront shopFront) {
            foreach (var x in ActiveTrades) {
                if (x.ShopFront == shopFront) return x;
            }
            return null;
        }
        public Trade GetTrade(ItemContainer feeContainer) {
            foreach (var x in ActiveTrades) {
                if (x.FeePaymentContainer == feeContainer) return x;
            }
            return null;
        }
        public bool CanSentTrade(BasePlayer sentBy, BasePlayer sentTo, out string reason) {
            reason = null;
            if (!Debug) {
                if (sentBy == sentTo) {
                    reason = GetPhrase("trade_help_noself", sentBy);
                    return false;
                }
            }
            if (IsCooledDown(sentBy, false)) {
                reason = $"You're in cooldown.\n<size=12><color=orange>{CooldownSecondsLeft(sentBy):0}</color> seconds left.</size>";
                return false;
            }
            if (!sentTo.IsConnected || sentTo.IsDead() || sentTo.IsSleeping()) {
                reason = $"<color=orange>{sentTo.displayName}</color> is dead, sleeping or not online.";
                return false;
            }
            if (GetTrade(sentBy, sentTo) != null || GetTrade(sentTo, sentBy) != null) {
                reason = "There's already a trade sent between you two.";
                return false;
            }
            if (!Config.Rules.CanTradeBuildingBlocked && !sentBy.CanBuild()) {
                reason = "You're building-blocked.";
                return false;
            }
            if (!Config.Rules.CanTradeBuildingBlocked && !sentTo.CanBuild()) {
                reason = $"<color=orange>{sentTo.displayName}</color> is building-blocked.";
                return false;
            }
            if (NoEscape != null) {
                if (!Config.Rules.CanTradeCombatBlocked && NoEscape.Call<bool>("IsCombatBlocked", sentBy)) {
                    reason = "You're combat-blocked.";
                    return false;
                }
                if (!Config.Rules.CanTradeRaidBlocked && NoEscape.Call<bool>("IsRaidBlocked", sentBy)) {
                    reason = "You're raid-blocked.";
                    return false;
                }
                if (!Config.Rules.CanTradeCombatBlocked && NoEscape.Call<bool>("IsCombatBlocked", sentTo)) {
                    reason = $"<color=orange>{sentTo.displayName}</color> is combat-blocked.";
                    return false;
                }
                if (!Config.Rules.CanTradeRaidBlocked && NoEscape.Call<bool>("IsRaidBlocked", sentTo)) {
                    reason = $"<color=orange>{sentTo.displayName}</color> is raid-blocked.";
                    return false;
                }
            }
            return true;
        }
        public bool IsTradingShopFront(ShopFront shopFront) {
            foreach (var x in ActiveTrades) {
                if (x.ShopFront == shopFront) return true;
            }
            return false;
        }
        public bool IsCooledDown(BasePlayer player, bool coolDownPlayer = true) {
            foreach (var group in Config.GroupCooldowns) {
                if (permission.UserHasGroup(player.UserIDString, group.Key)) {
                    if (CooledDownPlayers.ContainsKey(player.userID)) {
                        if (Time.realtimeSinceStartup - CooledDownPlayers[player.userID] > group.Value) {
                            if (coolDownPlayer) {
                                CooledDownPlayers[player.userID] = Time.realtimeSinceStartup;
                                return true;
                            }
                            else {
                                CooledDownPlayers.Remove(player.userID);
                                return false;
                            }
                        }
                        else {
                            return true;
                        }
                    }
                    else if (coolDownPlayer) {
                        CooledDownPlayers.Add(player.userID, Time.realtimeSinceStartup);
                        return true;
                    }
                }
            }
            return false;
        }
        public float CooldownSecondsLeft(BasePlayer player) {
            if (IsCooledDown(player, false)) {
                foreach (var group in Config.GroupCooldowns) {
                    if (permission.UserHasGroup(player.UserIDString, group.Key)) {
                        return group.Value - (Time.realtimeSinceStartup - CooledDownPlayers[player.userID]);
                    }
                }
            }
            return 0f;
        }
        public const string InviteEffect = "assets/bundled/prefabs/fx/invite_notice.prefab";
        public const string SuccessEffect = "assets/prefabs/building/wall.frame.shopfront/effects/metal_transaction_complete.prefab";
        public const string OpenEffect = "assets/prefabs/deployable/locker/effects/locker-deploy.prefab";
#region Permissions
        public const string UsePerm = "StaticTrader.use";
        public void InstallPermissions() {
            permission.RegisterPermission(UsePerm, this);
        }
        private bool HasPermission(BasePlayer player, string perm, bool quiet = false) {
            if (!permission.UserHasPermission(player.UserIDString, perm)) {
                if (!quiet) Print($"You need to have the \"{perm}\" permission.", player);
                return false;
            }
            return true;
        }
#endregion
#region Hooks
        private void OnServerInitialized() {
            Instance = this;
            InstallPermissions();
            InstallCommands();
            Loaded();
            RefreshPlugins();
        }
        private void Loaded() {
            if (Instance == null) return;
            if (ConfigFile == null) ConfigFile = new Core.Configuration.DynamicConfigFile($"{Manager.ConfigPath}{Path.DirectorySeparatorChar}{Name}.json");
            if (!ConfigFile.Exists()) {
                ConfigFile.WriteObject(Config = new RootConfig());
            }
            else {
                try {
                    Config = ConfigFile.ReadObject<RootConfig>();
                }
                catch (Exception exception) {
                    Puts($"Broken configuration: {exception.Message}");
                }
            }
            foreach (var player in BasePlayer.activePlayerList) {
                FetchProfileInfo(player.userID);
            }
        }
        private void Unload() {
            foreach (var player in BasePlayer.activePlayerList) {
                ClearAllUI(player);
            }
            foreach (var trade in ActiveTrades) {
                trade?.Clear(true);
            }
            ActiveTrades.Clear();
        }
        private void OnPluginLoaded(Plugin name) {
            RefreshPlugins();
        }
        private void OnPluginUnloaded(Plugin name) {
            RefreshPlugins();
        }
        private object OnShopCompleteTrade(ShopFront entity) {
            if (!IsTradingShopFront(entity)) return null;
            var trade = GetTrade(entity);
            trade.IsSuccessful = true;
            TakePlayerCurrency(trade.Target, trade.Fee);
            timer.In(1f, () => {
                var vendor = entity.vendorPlayer;
                if (vendor == null) return;
                var customer = entity.customerPlayer;
                if (customer == null) return;
                vendor.inventory.loot.Clear();
                vendor.inventory.loot.SendImmediate();
                customer.inventory.loot.Clear();
                customer.inventory.loot.SendImmediate();
                SendEffectTo(SuccessEffect, trade.Initiator);
                SendEffectTo(SuccessEffect, trade.Target);
                trade.Clear();
                IsCooledDown(trade.Initiator, true);
                IsCooledDown(trade.Target, true);
            }
            );
            return null;
        }
        private object OnEntityVisibilityCheck(BaseEntity ent, BasePlayer player, uint id, string debugName, float maximumDistance) {
            var shopFront = ent as ShopFront;
            if (shopFront == null) return null;
            if (IsTradingShopFront(shopFront)) {
                return true;
            }
            return null;
        }
        private object CanLootPlayer(BasePlayer looted, BasePlayer looter) {
            var trade = GetTrade(looter);
            if (trade != null && trade.FeePaymentContainer == looter.inventory.loot.containers[0]) {
                return true;
            }
            return null;
        }
        private void OnPlayerLootEnd(PlayerLoot playerLoot) {
            if (playerLoot.containers.Count == 0) return;
            FieldInfo fieldInfo = typeof(PlayerLoot).GetField("baseEntity", BindingFlags.NonPublic | BindingFlags.Instance);
            var player = (BaseEntity)fieldInfo.GetValue(playerLoot);
            var trade = GetTrade(playerLoot.containers[0]);
            if (trade != null) {
                var feeContainer = trade.FeePaymentContainer;
                if (feeContainer.itemList.Count == 0) {
                    Print(GetPhrase("trade_cancelled", trade.Initiator), trade.Initiator);
                    Print(GetPhrase("trade_cancelled", trade.Target), trade.Target);
                    trade.Clear(true);
                    ActiveTrades.Remove(trade);
                }
                else {
                    var item = feeContainer.itemList[0];
                    if (item.amount < trade.Fee) {
                        Print($"{GetPhrase("trade_failed", player.ToPlayer())} {GetPhrase("trade_failed_nomoney", player.ToPlayer(), Config.Fee.GetName())}", player.ToPlayer());
                        player.GiveItem(item);
                        trade.Clear(true);
                        ActiveTrades.Remove(trade);
                    }
                    else {
                        timer.In(0.2f, () => {
                            Instance.SendEffectTo(OpenEffect, trade.Target);
                            Instance.SendEffectTo(OpenEffect, trade.Initiator);
                            trade.Start();
                        }
                        );
                    }
                }
                return;
            }
            var shopFront = playerLoot.containers[0]?.entityOwner as ShopFront;
            if (shopFront != null && IsTradingShopFront(shopFront)) {
                trade = GetTrade(shopFront);
                if (!trade.IsSuccessful) {
                    Print(GetPhrase("trade_cancelled", trade.Initiator), trade.Initiator);
                    Print(GetPhrase("trade_cancelled", trade.Target), trade.Target);
                    if (trade.FeePaymentContainer != null && trade.FeePaymentContainer.itemList.Count != 0) player.GiveItem(trade.FeePaymentContainer.itemList[0]);
                    trade.Clear(true);
                }
                else {
                    Print(GetPhrase("trade_successful", trade.Initiator), trade.Initiator);
                    Print(GetPhrase("trade_successful", trade.Target), trade.Target);
                    trade.Clear();
                }
                ActiveTrades.Remove(trade);
            }
        }
        private void OnServerSave() {
            if (Instance == null) return;
            if (Config != null) ConfigFile.WriteObject(Config);
        }
        private void OnPlayerConnected(BasePlayer player) {
            FetchProfileInfo(player.userID);
        }
#endregion
#region CUI
        public const string PendingInviteUI = "HmmThisPluginIsReallyCoolLetsNotLeakIt";
        public const string TeamListUI = "HmmThisPluginIsReallyCoolLetsNotLeakItPls";
        public const int HeightOffset = 1000;
        public void ClearAllUI(BasePlayer player) {
            ClearPendingInviteUI(player);
            ClearTeamListUI(player, false);
        }
        public void ClearPendingInviteUI(BasePlayer player) {
            for (int i = 0; i < 5; i++) {
                CuiHelper.DestroyUi(player, PendingInviteUI);
            }
        }
        public void DrawPendingInviteUI(BasePlayer player, Trade trade) {
            if (PlayerTradeListFilter.ContainsKey(player.userID)) return;
            ClearPendingInviteUI(player);
            var other = trade.Initiator == player ? trade.Target : trade.Initiator;
            var container = new CuiElementContainer();
            var background = container.Add(new CuiPanel {
                Image = {
                    Color = $"0 0 0 0"
                }
                , RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = $"0 -{HeightOffset}", OffsetMax = $"0 -{HeightOffset}"
                }
                , CursorEnabled = false
            }
            , "Hud", PendingInviteUI);
            var fee = Config.Fee.CurrencyType == RootConfig.CurrencyTypes.None ? "" : $" (<b>{Config.Fee.GetValueName(trade.Fee, false)}</b>)";
            var panel = container.Add(new CuiPanel {
                Image = {
                    Color = $"0.15 0.15 0.15 0.6", Material = "assets/content/ui/uibackgroundblur.mat"
                }
                , RectTransform = {
                    AnchorMin = "0.4 0.175", AnchorMax = "0.6 0.275", OffsetMin = $"{Config.UINoticeXOffset} {HeightOffset + Config.UINoticeYOffset}", OffsetMax = $"{Config.UINoticeXOffset} {HeightOffset + Config.UINoticeYOffset}"
                }
            }
            , background);
            panel = container.Add(new CuiPanel {
                Image = {
                    Color = $"0.15 0.15 0.15 0.6"
                }
                , RectTransform = {
                    AnchorMin = "0.02 0.1", AnchorMax = "0.975 0.9"
                }
            }
            , panel);
            container.Add(new CuiLabel {
                Text = {
                    Text = $"<b>{other.displayName}</b> has sent you a trading invite.", FontSize = 12, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperCenter, Color = "1 1 1 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0 0", AnchorMax = $"1 0.85"
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"{Config.AcceptTradeCommand} {trade.Initiator.userID}", Color = "0.3 0.7 0.2 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0.05 0.15", AnchorMax = "0.495 0.5"
                }
                , Text = {
                    Text = $"Accept Invite{fee}", Color = "1 1 1 1", Align = TextAnchor.MiddleCenter, FontSize = 10
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"{Config.DeclineTradeCommand} {trade.Initiator.userID}", Color = "0.7 0.3 0.2 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0.505 0.15", AnchorMax = "0.95 0.5"
                }
                , Text = {
                    Text = "Decline Invite", Color = "1 1 1 1", Align = TextAnchor.MiddleCenter, FontSize = 10
                }
            }
            , panel);
            CuiHelper.AddUi(player, container);
        }
        public void ClearTeamListUI(BasePlayer player, bool refresh) {
            for (int i = 0; i < 5; i++) {
                CuiHelper.DestroyUi(player, TeamListUI);
            }
            if (!refresh) {
                UnlockPlayer(player);
                PlayerTradeListFilter.Remove(player.userID);
            }
        }
        public void DrawTeamListUI(BasePlayer player) {
            ClearTeamListUI(player, true);
            if (!PlayerTradeListFilter.ContainsKey(player.userID)) {
                PlayerTradeListFilter.Add(player.userID, new KeyValuePair<int, string>(0, string.Empty));
            }
            var settings = PlayerTradeListFilter[player.userID];
            var container = new CuiElementContainer();
            var teamMembers = GetTeam(player.currentTeam).members;
            //.Team?.members;
            var background = container.Add(new CuiPanel {
                Image = {
                    Color = $"0 0 0 0"
                }
                , RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = $"0 -{HeightOffset}", OffsetMax = $"0 -{HeightOffset}"
                }
                , CursorEnabled = true
            }
            , "Hud", TeamListUI);
            var panel = container.Add(new CuiPanel {
                Image = {
                    Color = $"0.15 0.15 0.15 0.6", Material = "assets/content/ui/uibackgroundblur.mat"
                }
                , RectTransform = {
                    AnchorMin = "0.3 0.175", AnchorMax = "0.7 0.375", OffsetMin = $"{Config.UINoticeXOffset} {HeightOffset + Config.UINoticeYOffset}", OffsetMax = $"{Config.UINoticeXOffset} {HeightOffset + Config.UINoticeYOffset}"
                }
            }
            , background);
            panel = container.Add(new CuiPanel {
                Image = {
                    Color = $"0.15 0.15 0.15 0.6"
                }
                , RectTransform = {
                    AnchorMin = "0.01 0.05", AnchorMax = "0.9875 0.95"
                }
            }
            , panel);
            var buttonOffset = 0f;
            var buttonOffsetSpacing = 25f;
            container.Add(new CuiLabel {
                Text = {
                    Text = $"SELECT A <b>PLAYER</b> TO <b>TRADE</b> WITH", FontSize = 14, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperLeft, Color = "1 1 1 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0.015 0", AnchorMax = $"1 0.925"
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"closeteamlist", Color = "0.9 0.3 0.2 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0.935 0.775", AnchorMax = "0.98 0.93"
                }
                , Text = {
                    Text = $"<b>X</b>", Color = "1 1 1 1", Align = TextAnchor.MiddleCenter, FontSize = 10
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"pageteamlist 1", Color = "0.9 0.8 0.3 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0.935 0.775", AnchorMax = "0.98 0.93", OffsetMin = $"{buttonOffset -= buttonOffsetSpacing} 0", OffsetMax = $"{buttonOffset} 1"
                }
                , Text = {
                    Text = $"<b>></b>", Color = "0 0 0 1", Align = TextAnchor.MiddleCenter, FontSize = 12
                }
            }
            , panel);
            container.Add(new CuiButton {
                Button = {
                    Command = $"pageteamlist -1", Color = "0.9 0.8 0.3 0.8"
                }
                , RectTransform = {
                    AnchorMin = $"0.935 0.775", AnchorMax = "0.98 0.93", OffsetMin = $"{buttonOffset -= buttonOffsetSpacing} 0", OffsetMax = $"{buttonOffset} 1"
                }
                , Text = {
                    Text = $"<b><</b>", Color = "0 0 0 1", Align = TextAnchor.MiddleCenter, FontSize = 12
                }
            }
            , panel);
            var players = Facepunch.Pool.GetList<BasePlayer>();
            if (teamMembers != null) {
                foreach (var member in teamMembers) {
                    var p = BasePlayer.FindByID(member);
                    if (!Debug && p == player) continue;
                    if (!p.IsConnected || (!string.IsNullOrEmpty(settings.Value) && !p.displayName.ToLower().Contains(settings.Value.ToLower().Trim()))) continue;
                    players.Add(p);
                }
            }
            if (!Config.TeamOnlyTradingList) {
                foreach (var p in BasePlayer.activePlayerList.Where(x => teamMembers == null ? true : !teamMembers.Contains(x.userID)).OrderBy(x => x.displayName)) {
                    if (!Debug && (p == player || players.Contains(p))) continue;
                    if (!string.IsNullOrEmpty(settings.Value) && !p.displayName.ToLower().Contains(settings.Value.ToLower().Trim())) continue;
                    players.Add(p);
                }
            }
            var totalPages = (int)Math.Ceiling((double)players.Count / 5);
            PlayerTradeListFilter[player.userID] = new KeyValuePair<int, string>(settings.Key < 0 ? totalPages - 1 : settings.Key >= totalPages ? 0 : settings.Key, settings.Value);
            settings = PlayerTradeListFilter[player.userID];
            var searchBar = container.Add(new CuiPanel {
                Image = {
                    Color = $"0.15 0.15 0.15 0.85"
                }
                , RectTransform = {
                    AnchorMin = $"0.55 0.775", AnchorMax = "0.83 0.93"
                }
            }
            , panel);
            container.Add(new CuiLabel {
                Text = {
                    Text = $"Search player...", FontSize = 10, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.3"
                }
                , RectTransform = {
                    AnchorMin = $"0.03 0", AnchorMax = $"1 1"
                }
            }
            , searchBar);
            container.Add(new CuiElement {
                Parent = searchBar, Components = {
                    new CuiInputFieldComponent {
                        Text = "", FontSize = 10, Command = $"filterteamlist", Align = TextAnchor.MiddleLeft, Color = "1 1 1 1", CharsLimit = 20
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.03 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            var pagePlayers = players.Skip(6 * settings.Key).Take(6);
            var length = 1f / 3.1f;
            var slotXOffset = 5f;
            var slotYOffset = -37.5f;
            var slotXOffsetSpacing = 165f;
            var slotYOffsetSpacing = 50f;
            if (pagePlayers.Any()) {
                for (int i = 0; i < 6; i++) {
                    var valid = i <= pagePlayers.Count() - 1;
                    var slot = container.Add(new CuiPanel {
                        Image = {
                            Color = $"0.05 0.05 0.05 {(valid ? 0.6 : 0.3)}"
                        }
                        , RectTransform = {
                            AnchorMin = "0 0.7", AnchorMax = $"{length} 1", OffsetMin = $"{slotXOffset} {slotYOffset}", OffsetMax = $"{slotXOffset} {slotYOffset + 1}"
                        }
                    }
                    , panel);
                    if (i <= pagePlayers.Count() - 1) {
                        var p = pagePlayers.ElementAt(i);
                        var info = FetchProfileInfo(p.userID);
                        var isTeamMate = teamMembers == null ? false : teamMembers.Contains(p.userID);
                        container.Add(new CuiElement {
                            Parent = slot, Components = {
                                Death.GetRawImage(info.Key, color : $"1 1 1 0.8"), new CuiRectTransformComponent {
                                    AnchorMin = "0.03 0.15", AnchorMax = "0.2 0.85"
                                }
                            }
                        }
                        );
                        container.Add(new CuiLabel {
                            Text = {
                                Text = $"<b>{info.Value}</b>", FontSize = 14, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperLeft, Color = "1 1 1 0.8"
                            }
                            , RectTransform = {
                                AnchorMin = $"0.25 0", AnchorMax = $"1 0.85"
                            }
                        }
                        , slot);
                        container.Add(new CuiLabel {
                            Text = {
                                Text = isTeamMate ? "Team Member" : $"{p.userID}", FontSize = 10, Font = "robotocondensed-regular.ttf", Align = TextAnchor.LowerLeft, Color = isTeamMate ? "0.3 0.9 0.2 0.5" : "0.75 0.75 0.75 0.5"
                            }
                            , RectTransform = {
                                AnchorMin = $"0.25 0.2", AnchorMax = $"1 1"
                            }
                        }
                        , slot);
                        container.Add(new CuiButton {
                            Button = {
                                Command = $"{Config.TradeCommand} {p.userID}", Color = "0 0 0 0"
                            }
                            , RectTransform = {
                                AnchorMin = $"0 0", AnchorMax = "1 1"
                            }
                            , Text = {
                                Color = "0 0 0 0"
                            }
                        }
                        , slot);
                    }
                    slotXOffset += slotXOffsetSpacing;
                    if (i % 3 == 2) {
                        slotXOffset = 5f;
                        slotYOffset -= slotYOffsetSpacing - 5f;
                    }
                }
            }
            else container.Add(new CuiLabel {
                Text = {
                    Text = Config.TeamOnlyTradingList && GetTeam(player.currentTeam) == null ? "You're not in a team." : $"No players have been found.", FontSize = 8, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, Color = "1 1 1 0.2"
                }
                , RectTransform = {
                    AnchorMin = $"0 0.05", AnchorMax = $"1 0.75"
                }
            }
            , panel);
            CuiHelper.AddUi(player, container);
            pagePlayers = null;
            Facepunch.Pool.FreeList(ref players);
            LockPlayer(player);
        }
        public class Death {
            public static string GetImage(string url, bool isPng = true, ulong skin = 0) {
                try {
                    var name = GetStringChecksum(url);
                    if (string.IsNullOrEmpty(url)) return string.Empty;
                    if ((bool)Instance.ImageLibrary.Call("HasImage", name, skin)) {
                        var success = Instance.ImageLibrary.Call("GetImage", name, skin);
                        return !isPng ? null : (string)success;
                    }
                    else {
                        Instance.ImageLibrary.Call("AddImage", url, name, skin);
                        return !isPng ? url : null;
                    }
                }
                catch {
                }
                return string.Empty;
            }
            public static CuiRawImageComponent GetRawImage(string url, ulong skin = 0, string color = "", float fade = 0.3f) {
                var _url = GetImage(url, isPng : false, skin : skin);
                var _png = GetImage(url, skin : skin);
                return new CuiRawImageComponent {
                    Url = _url, Png = _png, Color = color, FadeIn = fade
                }
                ;
            }
        }
        public static string GetStringChecksum(string value) {
            if (value.Length <= 3) return null;
            using (var md5 = MD5.Create()) {
                var hash = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(value));
                return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
            }
        }
#endregion
#region Lang
        protected override void LoadDefaultMessages() {
            var defaultMessages = new Dictionary<string, string>() {
                ["trade_sent"]
                = "You've sent a trade request to <color=orange>{0}</color>.", ["trade_received"] = "<color=orange>{0}</color> sent you a trade request.", ["trade_payment"] = "You'll pay a fee of <color=orange>{0}</color> when the trade is successful.", ["trade_notrade"] = "There's no trade exchanged between you and that player/any player.", ["trade_title"] = "<b>{0}</b> has sent you a trading invite.", ["trade_accept"] = "Accept Invite", ["trade_decline"] = "Decline Invite", ["trade_expired"] = "The trade between you and <color=orange>{0}</color> has expired.", ["trade_expired2"] = "The trade between <color=orange>{0}</color> and you has expired.", ["trade_declined"] = "<color=orange>{0}</color> has <color=red>declined</color> your trade request.", ["trade_declined2"] = "Trade with <color=orange>{0}</color> has been <color=red>declined</color>.", ["trade_nomoneys"] = "You don't have enough <color=orange>{0}</color> to pay the trading fee.", ["trade_nomoneys2"] = "<color=orange>{0}</color> doesn't have enough <color=orange>{1}</color> to pay the trading fee.", ["trade_cancelled"] = "Trade <color=red>cancelled</color>.", ["trade_successful"] = "Trade <color=green>successful</color>.", ["trade_failed"] = "Trade <color=red>failed</color>.", ["trade_failed_nomoney"] = "Not enough <color=orange>{0}</color> for the processing fee.", ["trade_help_accept"] = "<size=10>Do <color=green>/atrade</color> or <color=green>/atrade {0}</color> to accept it.Do <color=red>/dtrade</color> to decline.</size>", ["trade_help_noname"] = "Please enter the player name you'd like to trade with.", ["trade_help_noplayer"] = "That player doesn't exist.", ["trade_nopermission"] = "<color=orange>{0}</color> does not have the permission to trade.", ["trade_noself"] = "You cannot trade with yourself.",
            }
            ;
            lang.RegisterMessages(defaultMessages, this, lang : "en");
            // Use: lang.GetMessage ( "trade_sent", this, userID );
        }
        public string GetPhrase(string key, BasePlayer player, params string[] parameters) {
            try {
                return string.Format(lang.GetMessage(key, this, player.UserIDString), parameters);
            }
            catch {
                return key;
            }
        }
#endregion
#region Plugins
        private Plugin ImageLibrary;
        private Plugin NoEscape;
        private Plugin ServerRewards;
        private Plugin Economics;
        private Plugin OtherPlugin;
#endregion
#region Helpers
        private readonly Regex RegexAvatar = new Regex(@"<avatarFull><!\[CDATA\[(.*)\]\]></avatarFull>");
        private readonly Regex RegexUsername = new Regex(@"<steamID><!\[CDATA\[(.*)\]\]></steamID>");
        public void Print(object message, BasePlayer player = null) {
            if (player == null) PrintToChat($"<color=orange>{Name}</color>: {message}");
            else PrintToChat(player, $"<color=orange>{Name}</color> (OY): {message}");
        }
        public float Scale(float oldValue, float oldMin, float oldMax, float newMin, float newMax) {
            var num = oldMax - oldMin;
            var num2 = newMax - newMin;
            return (oldValue - oldMin) * num2 / num + newMin;
        }
        public string Join(string[] array, string separator, string lastSeparator = null) {
            if (string.IsNullOrEmpty(lastSeparator)) {
                lastSeparator = separator;
            }
            if (array.Length == 0) {
                return string.Empty;
            }
            if (array.Length == 1) {
                return array[0];
            }
            List<string> list = new List<string>();
            for (int i = 0; i < array.Length - 1; i++) {
                list.Add(array[i]);
            }
            return string.Join(separator, list.ToArray()) + $"{lastSeparator}{array[array.Length - 1]}";
        }
        public void EnsurePlayerToPlayer(BasePlayer player, BasePlayer player2) {
            var connection = player.Connection;
            if (Network.Net.sv.write.Start() == false || connection == null) return;
            ++connection.validate.entityUpdates;
            var saveInfo = new BaseNetworkable.SaveInfo() {
                forConnection = connection, forDisk = false
            }
            ;
            Network.Net.sv.write.PacketID(Network.Message.Type.Entities);
            Network.Net.sv.write.UInt32(connection.validate.entityUpdates);
            player2.ToStreamForNetwork((Stream)Network.Net.sv.write, saveInfo);
            Network.Net.sv.write.Send(new SendInfo(connection));
        }
        public void SendEffectTo(string effect, BasePlayer player) {
            if (player == null) return;
            var effectInstance = new Effect();
            effectInstance.Init(Effect.Type.Generic, player, 0, Vector3.up, Vector3.zero);
            effectInstance.pooledstringid = StringPool.Get(effect);
            Net.sv.write.Start();
            Net.sv.write.PacketID(Message.Type.Effect);
            effectInstance.WriteToStream(Network.Net.sv.write);
            Net.sv.write.Send(new SendInfo(player.net.connection));
            effectInstance.Clear();
        }
        public void GetSteamProfileInfo(ulong userId, Action<string, string> callback) {
            if (callback == null) return;
            webrequest.Enqueue($"http://steamcommunity.com/profiles/{userId}?xml=1", null, (code, response) => {
                try {
                    if (code != 200 || response == null) return;
                    callback.Invoke(RegexAvatar.Match(response).Groups[1].ToString(), RegexUsername.Match(response).Groups[1].ToString());
                }
                catch {
                }
            }
            , Instance);
        }
        public KeyValuePair<string, string> FetchProfileInfo(ulong userId) {
            if (PlayersSteamInfo.ContainsKey(userId)) return PlayersSteamInfo[userId];
            GetSteamProfileInfo(userId, (avatar, username) => {
                PlayersSteamInfo.Add(userId, new KeyValuePair<string, string>(avatar, username));
            }
            );
            return new KeyValuePair<string, string>("https://steamuserimages-a.akamaihd.net/ugc/885384897182110030/F095539864AC9E94AE5236E04C8CA7C2725BCEFF/", BasePlayer.FindByID(userId)?.displayName);
        }
        public void RefreshPlugins() {
            if (ImageLibrary == null || !ImageLibrary.IsLoaded) ImageLibrary = plugins.Find(nameof(ImageLibrary));
            if (ServerRewards == null || !ServerRewards.IsLoaded) ServerRewards = plugins.Find(nameof(ServerRewards));
            if (Economics == null || !Economics.IsLoaded) Economics = plugins.Find(nameof(Economics));
            if (NoEscape == null || !NoEscape.IsLoaded) NoEscape = plugins.Find(nameof(NoEscape));
            if (Config.Fee.CurrencyType == RootConfig.CurrencyTypes.Other) {
                OtherPlugin = plugins.Find(Config.Fee.OtherSettings.PluginName);
                OtherPlugin?.Load();
            }
        }
        public Dictionary<BasePlayer, BaseMountable> LockedPlayers {
            get;
            set;
        }
        = new Dictionary<BasePlayer, BaseMountable>();
        public void LockPlayer(BasePlayer player) {
            if (LockedPlayers.ContainsKey(player) || player.isMounted) return;
            var position = player.transform.position;
            var mountable = GameManager.server.CreateEntity("assets/prefabs/vehicle/seats/standingdriver.prefab", player.transform.position, player.transform.rotation, true) as BaseMountable;
            mountable.transform.localPosition = Vector3.zero;
            mountable.transform.localEulerAngles = Vector3.zero;
            mountable.transform.SetPositionAndRotation(position, player.transform.rotation);
            mountable.Spawn();
            EnableGlobalBroadcast(mountable, true);
            player.EnsureDismounted();
            player.MountObject(mountable);
            mountable.MountPlayer(player);
            mountable.transform.position = position;
            mountable.SendNetworkUpdate();
            LockedPlayers.Add(player, mountable);
        }
        public void UnlockPlayer(BasePlayer player) {
            try {
                if (LockedPlayers == null || !LockedPlayers.ContainsKey(player) && player.isMounted) return;
                LockedPlayers[player].Kill();
                player?.EnsureDismounted();
                player?.DismountObject();
                LockedPlayers.Remove(player);
            }
            catch {
            }
        }
#endregion
#region Methods
        public static BasePlayer FindAwakeOrSleeping(string strNameOrIDOrIP) {
            var player = BasePlayer.Find(strNameOrIDOrIP);
            if (player == null) return BasePlayer.FindSleeping(strNameOrIDOrIP);
            return player;
        }
        public void EnableGlobalBroadcast(BaseEntity entity, bool wants) {
            if (entity.globalBroadcast == wants) {
                return;
            }
            entity.globalBroadcast = wants;
            entity.UpdateNetworkGroup();
        }
        private static RelationshipManager.PlayerTeam GetTeam(ulong teamId) => RelationshipManager.Instance.FindTeam(teamId);
        public void InstallCommands() {
            cmd.AddChatCommand(Config.TradeCommand, this, (player, command, args) => SendTrade(player, args));
            cmd.AddChatCommand(Config.AcceptTradeCommand, this, (player, command, args) => AcceptTrade(player, args));
            cmd.AddChatCommand(Config.DeclineTradeCommand, this, (player, command, args) => DeclineTrade(player, args));
            cmd.AddChatCommand(Config.TradeListCommand, this, (player, command, args) => ListTrade(player, args));
            cmd.AddConsoleCommand(Config.TradeCommand, this, (arg) => {
                SendTrade(arg.Player(), arg.Args);
                return true;
            }
            );
            cmd.AddConsoleCommand(Config.AcceptTradeCommand, this, (arg) => {
                AcceptTrade(arg.Player(), arg.Args);
                return true;
            }
            );
            cmd.AddConsoleCommand(Config.DeclineTradeCommand, this, (arg) => {
                DeclineTrade(arg.Player(), arg.Args);
                return true;
            }
            );
            cmd.AddConsoleCommand(Config.TradeListCommand, this, (arg) => {
                ListTrade(arg.Player(), arg.Args);
                return true;
            }
            );
        }
        public void SendTrade(BasePlayer player, string[] args) {
            if (player == null || !HasPermission(player, UsePerm)) return;
            ClearTeamListUI(player, false);
            if (args.Length == 0) {
                Print(GetPhrase("trade_successful", player), player);
                return;
            }
            var filter = Join(args, " ").ToLower().Trim();
            var targetPlayer = BasePlayer.activePlayerList.FirstOrDefault(x => x.displayName.ToLower().Trim().Contains(filter) || x.UserIDString.Contains(filter));
            if (targetPlayer == null) {
                Print(GetPhrase("trade_help_noplayer", player), player);
                return;
            }
            if (!HasPermission(targetPlayer, UsePerm)) {
                Print(GetPhrase("trade_help_nopermission", player, targetPlayer.displayName), player);
                return;
            }
            var reason = string.Empty;
            if (!CanSentTrade(player, targetPlayer, out reason)) {
                Print($"<color=orange>{player.displayName}</color> -> <color=orange>{targetPlayer.displayName}</color>: {reason}", player);
                return;
            }
            var trade = new Trade(player, targetPlayer);
            trade.Timer = timer.In(Config.Timeout, () => {
                Print(GetPhrase("trade_expired", player, targetPlayer.displayName), player);
                Print(GetPhrase("trade_expired2", targetPlayer, player.displayName), targetPlayer);
                trade.Clear();
                ActiveTrades.Remove(trade);
            }
            );
            trade.Fee = trade.GetFee();
            ActiveTrades.Add(trade);
            Print(GetPhrase("trade_sent", player, targetPlayer.displayName), player);
            Print($"{GetPhrase("trade_received", targetPlayer, player.displayName)}{(Config.Fee.CurrencyType == RootConfig.CurrencyTypes.None ? "" : $" {
                GetPhrase("trade_payment", targetPlayer, Config.Fee.GetValueName(trade.Fee, true))
            }
            ")}\n{GetPhrase("trade_help_accept", targetPlayer, player.displayName)}", targetPlayer);
            if (Config.ShowUINotice) DrawPendingInviteUI(targetPlayer, trade);
            SendEffectTo(InviteEffect, trade.Initiator);
            SendEffectTo(InviteEffect, trade.Target);
        }
        public void AcceptTrade(BasePlayer player, string[] args) {
            if (player == null || !HasPermission(player, UsePerm)) return;
            ClearTeamListUI(player, false);
            var trade = (Trade)null;
            if (args.Length == 0) {
                trade = GetTrade(player);
            }
            else {
                var filter = Join(args, " ").ToLower().Trim();
                var targetPlayer = BasePlayer.activePlayerList.FirstOrDefault(x => x.displayName.ToLower().Trim().Contains(filter) || x.UserIDString.Contains(filter));
                if (targetPlayer == null) {
                    Print(GetPhrase("trade_help_noplayer", player), player);
                    return;
                }
                trade = GetTrade(targetPlayer, player);
            }
            if (trade == null) {
                Print(GetPhrase("trade_notrade", player), player);
                return;
            }
            ClearPendingInviteUI(trade.Target);
            ClearPendingInviteUI(trade.Initiator);
            trade.Fee = trade.GetFee();
            trade.Timer?.Destroy();
            trade.Timer = null;
            switch (Config.Fee.CurrencyType) {
                case RootConfig.CurrencyTypes.Item : trade.PlayerLootContainer(player, "generic_resizable", trade.GetFeePaymentContainer());
                break;
                default : if (Config.Fee.CurrencyType != RootConfig.CurrencyTypes.None && !PlayerHasCurrency(trade.Target, trade.Fee)) {
                    Print(GetPhrase("trade_nomoneys", trade.Target, Config.Fee.GetName()), trade.Target);
                    Print(GetPhrase("trade_nomoneys2", trade.Target, trade.Target.displayName, Config.Fee.GetName()), trade.Initiator);
                }
                else {
                    Instance.SendEffectTo(OpenEffect, trade.Target);
                    Instance.SendEffectTo(OpenEffect, trade.Initiator);
                    timer.In(0.15f, trade.Start);
                }
                break;
            }
        }
        public void DeclineTrade(BasePlayer player, string[] args) {
            if (player == null || !HasPermission(player, UsePerm)) return;
            ClearTeamListUI(player, false);
            var trade = (Trade)null;
            if (args.Length == 0) {
                trade = GetTrade(player);
            }
            else {
                var filter = Join(args, " ").ToLower().Trim();
                var targetPlayer = BasePlayer.activePlayerList.FirstOrDefault(x => x.displayName.ToLower().Trim().Contains(filter) || x.UserIDString.Contains(filter));
                if (targetPlayer == null) {
                    Print(GetPhrase("trade_help_noplayer", player), player);
                    return;
                }
                trade = GetTrade(player, targetPlayer);
            }
            if (trade == null) {
                Print(GetPhrase("trade_notrade", player), player);
                return;
            }
            Print(GetPhrase("trade_declined", trade.Initiator, trade.Target.displayName), trade.Initiator);
            Print(GetPhrase("trade_declined2", trade.Target, trade.Initiator.displayName), trade.Target);
            ClearPendingInviteUI(trade.Target);
            ClearPendingInviteUI(trade.Initiator);
            if (Config.TriggerCooldownOnDecline) {
                IsCooledDown(trade.Initiator, true);
            }
            trade.Clear();
            ActiveTrades.Remove(trade);
        }
        public void ListTrade(BasePlayer player, string[] args) {
            if (player == null || !HasPermission(player, UsePerm)) return;
            DrawTeamListUI(player);
        }
        [ConsoleCommand("closeteamlist")]
        private void CloseTeamList(ConsoleSystem.Arg arg) {
            var player = arg.Player();
            if (player == null) return;
            ClearTeamListUI(arg.Player(), false);
        }
        [ConsoleCommand("filterteamlist")]
        private void FilterTeamList(ConsoleSystem.Arg arg) {
            var player = arg.Player();
            if (player == null) return;
            var old = PlayerTradeListFilter[player.userID];
            PlayerTradeListFilter[player.userID] = new KeyValuePair<int, string>(old.Key, Join(arg.Args, " "));
            DrawTeamListUI(player);
        }
        [ConsoleCommand("pageteamlist")]
        private void PageTeamList(ConsoleSystem.Arg arg) {
            var player = arg.P
// ... [Code preview truncated due to length. Full source in attached file] ...

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