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

FREE AutomaticAuthorization : 1.3.3 1.3.3

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Oxide.Plugins
{
    [Info("Automatic Authorization", "k1lly0u/Arainrr", "1.3.3", ResourceId = 2063)]
    [Description("Shared cupboards, turrets, locks with teams, clans, friends")]
    public class AutomaticAuthorization : RustPlugin
    {
        #region Fields

        [PluginReference]
        private readonly Plugin Clans, Friends, Bank;

        private const string PERMISSION_USE = "automaticauthorization.use";

        private readonly object _true = true;
        private readonly Dictionary<ulong, EntityCache> _playerEntities = new Dictionary<ulong, EntityCache>();

        private enum ShareType
        {
            None,
            Teams,
            Friends,
            Clans
        }

        [Flags]
        private enum AutoAuthType
        {
            Turret = 1 << 0,
            Cupboard = 1 << 1,
            CodeLock = 1 << 2,
            All = -1,
        }

        private class EntityCache
        {
            public readonly HashSet<AutoTurret> autoTurrets = new HashSet<AutoTurret>();
            public readonly HashSet<BuildingPrivlidge> buildingPrivlidges = new HashSet<BuildingPrivlidge>();
            public readonly HashSet<CodeLock> codeLocks = new HashSet<CodeLock>();
        }

        #endregion Fields

        #region Oxide Hooks

        private void Init()
        {
            LoadData();
            UpdateData();

            permission.RegisterPermission(PERMISSION_USE, this);

            cmd.AddChatCommand(configData.Chat.ChatCommand, this, nameof(CmdAutoAuth));
            cmd.AddChatCommand(configData.Chat.UICommand, this, nameof(CmdAutoAuthUI));

            Unsubscribe(nameof(OnEntitySpawned));
            if (!configData.TeamsShare.Enabled)
            {
                Unsubscribe(nameof(OnTeamLeave));
                Unsubscribe(nameof(OnTeamKick));
                Unsubscribe(nameof(OnTeamDisbanded));
                Unsubscribe(nameof(OnTeamAcceptInvite));
            }
            if (!configData.FriendsShare.Enabled)
            {
                Unsubscribe(nameof(OnFriendAdded));
                Unsubscribe(nameof(OnFriendRemoved));
            }
            if (!configData.ClansShare.Enabled)
            {
                Unsubscribe(nameof(OnClanUpdate));
                Unsubscribe(nameof(OnClanDestroy));
                Unsubscribe(nameof(OnClanMemberGone));
            }
        }

        private void OnServerInitialized()
        {
            Subscribe(nameof(OnEntitySpawned));
            foreach (var serverEntity in BaseNetworkable.serverEntities)
            {
                var autoTurret = serverEntity as AutoTurret;
                if (autoTurret != null)
                {
                    CheckEntitySpawned(autoTurret);
                    continue;
                }
                var buildingPrivlidge = serverEntity as BuildingPrivlidge;
                if (buildingPrivlidge != null)
                {
                    CheckEntitySpawned(buildingPrivlidge);
                }
                var codeLock = serverEntity as CodeLock;
                if (codeLock != null)
                {
                    CheckEntitySpawned(codeLock);
                }
            }
        }

        private void OnServerSave()
        {
            timer.Once(Random.Range(0f, 60f), SaveData);
        }

        private void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                DestroyUI(player);
            }
            SaveData();
        }

        private void OnEntitySpawned(AutoTurret autoTurret)
        {
            CheckEntitySpawned(autoTurret, true);
        }

        private void OnEntitySpawned(BuildingPrivlidge buildingPrivlidge)
        {
            CheckEntitySpawned(buildingPrivlidge, true);
        }

        private void OnEntitySpawned(CodeLock codeLock)
        {
            CheckEntitySpawned(codeLock, true);
        }

        private void OnEntityKill(AutoTurret autoTurret)
        {
            CheckEntityKill(autoTurret);
        }

        private void OnEntityKill(BuildingPrivlidge buildingPrivlidge)
        {
            CheckEntityKill(buildingPrivlidge);
        }

        private void OnEntityKill(CodeLock codeLock)
        {
            CheckEntityKill(codeLock);
        }

        private void CanChangeCode(BasePlayer player, CodeLock codeLock, string code, bool isGuest)
        {
            NextFrame(() =>
            {
                if (!isGuest ? codeLock.code != code : codeLock.guestCode != code)
                {
                    return;
                }
                var parentEntity = codeLock.GetParentEntity();
                var ownerId = codeLock.OwnerID.IsSteamId() ? codeLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
                if (!ownerId.IsSteamId())
                {
                    return;
                }
                UpdateAuthList(ownerId, AutoAuthType.CodeLock);
            });
        }

        private object CanUseLockedEntity(BasePlayer player, BaseLock baseLock)
        {
            if (player == null || baseLock == null || !baseLock.IsLocked())
            {
                return null;
            }
            var parentEntity = baseLock.GetParentEntity();
            var ownerId = baseLock.OwnerID.IsSteamId() ? baseLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
            if (!ownerId.IsSteamId() || ownerId == player.userID)
            {
                return null;
            }
            if (!permission.UserHasPermission(ownerId.ToString(), PERMISSION_USE))
            {
                return null;
            }

            // Ignore the bank boxes
            if (IsBankBox(parentEntity))
            {
                return null;
            }

            var shareData = GetShareData(ownerId, true);
            if (CanSharingLock(baseLock, parentEntity, shareData, ShareType.Teams, ownerId, player.userID))
            {
                return _true;
            }
            if (CanSharingLock(baseLock, parentEntity, shareData, ShareType.Friends, ownerId, player.userID))
            {
                return _true;
            }
            if (CanSharingLock(baseLock, parentEntity, shareData, ShareType.Clans, ownerId, player.userID))
            {
                return _true;
            }
            return null;
        }

        #endregion Oxide Hooks

        #region Helpers

        private static bool CanShareLockedEntity(BaseEntity parentEntity, StoredData.LockShareEntry lockShareEntry)
        {
            if (!lockShareEntry.enabled)
            {
                return false;
            }
            return parentEntity is Door ? lockShareEntry.door :
                    parentEntity is BoxStorage ? lockShareEntry.box : lockShareEntry.other;
        }

        private static void SendUnlockedEffect(CodeLock codeLock)
        {
            if (codeLock.effectUnlocked.isValid)
            {
                Effect.server.Run(codeLock.effectUnlocked.resourcePath, codeLock.transform.position);
            }
        }

        private static void CheckShareData(StoredData.ShareEntry shareEntry, ConfigData.ShareSettings shareSettings)
        {
            if (!shareSettings.Enabled)
            {
                shareEntry.enabled = false;
            }
            if (!shareSettings.ShareCupboard)
            {
                shareEntry.cupboard = false;
            }
            if (!shareSettings.ShareTurret)
            {
                shareEntry.turret = false;
            }
            if (!shareSettings.KeyLock.Enabled)
            {
                shareEntry.keyLock.enabled = false;
            }
            if (!shareSettings.KeyLock.ShareDoor)
            {
                shareEntry.keyLock.door = false;
            }
            if (!shareSettings.KeyLock.ShareBox)
            {
                shareEntry.keyLock.box = false;
            }
            if (!shareSettings.KeyLock.ShareOtherEntity)
            {
                shareEntry.keyLock.other = false;
            }
            if (!shareSettings.CodeLock.Enabled)
            {
                shareEntry.codeLock.enabled = false;
            }
            if (!shareSettings.CodeLock.ShareDoor)
            {
                shareEntry.codeLock.door = false;
            }
            if (!shareSettings.CodeLock.ShareBox)
            {
                shareEntry.codeLock.box = false;
            }
            if (!shareSettings.CodeLock.ShareOtherEntity)
            {
                shareEntry.codeLock.other = false;
            }
        }

        #endregion Helpers

        #region Methods

        #region Entity Spawn / Kill

        private void CheckEntitySpawned(AutoTurret autoTurret, bool justCreated = false)
        {
            if (autoTurret == null || !autoTurret.OwnerID.IsSteamId())
            {
                return;
            }
            EntityCache entityCache;
            if (!_playerEntities.TryGetValue(autoTurret.OwnerID, out entityCache))
            {
                entityCache = new EntityCache();
                _playerEntities.Add(autoTurret.OwnerID, entityCache);
            }
            entityCache.autoTurrets.Add(autoTurret);

            if (justCreated && permission.UserHasPermission(autoTurret.OwnerID.ToString(), PERMISSION_USE))
            {
                AuthToTurret(new HashSet<AutoTurret> { autoTurret }, autoTurret.OwnerID, true);
            }
        }

        private void CheckEntitySpawned(BuildingPrivlidge buildingPrivlidge, bool justCreated = false)
        {
            if (buildingPrivlidge == null || !buildingPrivlidge.OwnerID.IsSteamId())
            {
                return;
            }
            EntityCache entityCache;
            if (!_playerEntities.TryGetValue(buildingPrivlidge.OwnerID, out entityCache))
            {
                entityCache = new EntityCache();
                _playerEntities.Add(buildingPrivlidge.OwnerID, entityCache);
            }
            entityCache.buildingPrivlidges.Add(buildingPrivlidge);

            if (justCreated && permission.UserHasPermission(buildingPrivlidge.OwnerID.ToString(), PERMISSION_USE))
            {
                AuthToCupboard(new HashSet<BuildingPrivlidge> { buildingPrivlidge }, buildingPrivlidge.OwnerID, true);
            }
        }

        private void CheckEntitySpawned(CodeLock codeLock, bool justCreated = false)
        {
            if (codeLock == null)
            {
                return;
            }
            var parentEntity = codeLock.GetParentEntity();
            if (parentEntity != null && IsBankBox(parentEntity))
            {
                return;
            }
            var ownerId = codeLock.OwnerID.IsSteamId() ? codeLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
            if (!ownerId.IsSteamId())
            {
                return;
            }
            EntityCache entityCache;
            if (!_playerEntities.TryGetValue(ownerId, out entityCache))
            {
                entityCache = new EntityCache();
                _playerEntities.Add(ownerId, entityCache);
            }
            entityCache.codeLocks.Add(codeLock);

            if (justCreated && permission.UserHasPermission(ownerId.ToString(), PERMISSION_USE))
            {
                AuthToCodeLock(new HashSet<CodeLock> { codeLock }, ownerId, true);
            }
        }

        private void CheckEntityKill(AutoTurret autoTurret)
        {
            if (autoTurret == null || !autoTurret.OwnerID.IsSteamId())
            {
                return;
            }
            EntityCache entityCache;
            if (_playerEntities.TryGetValue(autoTurret.OwnerID, out entityCache))
            {
                entityCache.autoTurrets.Remove(autoTurret);
            }
        }

        private void CheckEntityKill(BuildingPrivlidge buildingPrivlidge)
        {
            if (buildingPrivlidge == null || !buildingPrivlidge.OwnerID.IsSteamId())
            {
                return;
            }
            EntityCache entityCache;
            if (_playerEntities.TryGetValue(buildingPrivlidge.OwnerID, out entityCache))
            {
                entityCache.buildingPrivlidges.Remove(buildingPrivlidge);
            }
        }

        private void CheckEntityKill(CodeLock codeLock)
        {
            if (codeLock == null)
            {
                return;
            }
            var parentEntity = codeLock.GetParentEntity();
            var ownerId = codeLock.OwnerID.IsSteamId() ? codeLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
            if (!ownerId.IsSteamId())
            {
                return;
            }
            EntityCache entityCache;
            if (_playerEntities.TryGetValue(ownerId, out entityCache))
            {
                entityCache.codeLocks.Remove(codeLock);
            }
        }

        #endregion Entity Spawn / Kill

        private void UpdateAuthList(ulong playerId, AutoAuthType autoAuthType)
        {
            if (!permission.UserHasPermission(playerId.ToString(), PERMISSION_USE))
            {
                return;
            }
            EntityCache entityCache;
            if (!_playerEntities.TryGetValue(playerId, out entityCache))
            {
                return;
            }
            if (autoAuthType.HasFlag(AutoAuthType.Turret))
            {
                AuthToTurret(entityCache.autoTurrets, playerId);
            }
            if (autoAuthType.HasFlag(AutoAuthType.Cupboard))
            {
                AuthToCupboard(entityCache.buildingPrivlidges, playerId);
            }
            if (autoAuthType.HasFlag(AutoAuthType.CodeLock))
            {
                AuthToCodeLock(entityCache.codeLocks, playerId);
            }
        }

        private void AuthToTurret(HashSet<AutoTurret> autoTurrets, ulong playerId, bool justCreated = false)
        {
            if (autoTurrets.Count <= 0)
            {
                return;
            }
            var authList = GetAuthorNameIDs(playerId, AutoAuthType.Turret);
            foreach (var autoTurret in autoTurrets)
            {
                if (autoTurret == null || autoTurret.IsDestroyed)
                {
                    continue;
                }
                var isOnline = autoTurret.IsOnline();
                if (isOnline)
                {
                    autoTurret.SetIsOnline(false);
                }

                autoTurret.authorizedPlayers.Clear();
                foreach (var friend in authList)
                {
                    autoTurret.authorizedPlayers.Add(friend);
                }

                if (isOnline)
                {
                    autoTurret.SetIsOnline(true);
                }
                autoTurret.SendNetworkUpdate();
            }
            if (justCreated && configData.Chat.SendMessage && authList.Count > 1)
            {
                var player = BasePlayer.FindByID(playerId);
                if (player != null)
                {
                    Print(player, Lang("TurretSuccess", player.UserIDString, authList.Count - 1, autoTurrets.Count));
                }
            }
        }

        private void AuthToCupboard(HashSet<BuildingPrivlidge> buildingPrivlidges, ulong playerId, bool justCreated = false)
        {
            if (buildingPrivlidges.Count <= 0)
            {
                return;
            }
            var authList = GetAuthorNameIDs(playerId, AutoAuthType.Cupboard);
            foreach (var buildingPrivlidge in buildingPrivlidges)
            {
                if (buildingPrivlidge == null || buildingPrivlidge.IsDestroyed)
                {
                    continue;
                }
                buildingPrivlidge.authorizedPlayers.Clear();
                foreach (var friend in authList)
                {
                    buildingPrivlidge.authorizedPlayers.Add(friend);
                }
                buildingPrivlidge.SendNetworkUpdate();
            }
            if (justCreated && configData.Chat.SendMessage && authList.Count > 1)
            {
                var player = BasePlayer.FindByID(playerId);
                if (player != null)
                {
                    Print(player, Lang("CupboardSuccess", player.UserIDString, authList.Count - 1, buildingPrivlidges.Count));
                }
            }
        }

        private void AuthToCodeLock(HashSet<CodeLock> codeLocks, ulong playerId, bool justCreated = false)
        {
            if (codeLocks.Count <= 0)
            {
                return;
            }
            foreach (var codeLock in codeLocks)
            {
                if (codeLock == null || codeLock.IsDestroyed)
                {
                    continue;
                }
                codeLock.whitelistPlayers.Clear(); // only owner id
                codeLock.whitelistPlayers.Add(playerId);
                
                codeLock.guestPlayers.Clear(); // excluding owner id
                var authList = GetAuthorIDsForCodeLock(playerId, codeLock);
                foreach (var friend in authList)
                {
                    codeLock.guestPlayers.Add(friend);
                }
                codeLock.SendNetworkUpdate();
            }
        }

        private List<PlayerNameID> GetAuthorNameIDs(ulong playerId, AutoAuthType autoAuthType)
        {
            if (autoAuthType == AutoAuthType.CodeLock)
            {
                PrintError("Cannot be used for code locks");
                return new List<PlayerNameID>();
            }
            var authList = GetAuthIds(playerId, autoAuthType);
            return authList.Select(userid => new PlayerNameID { userid = userid, username = RustCore.FindPlayerById(userid)?.displayName ?? string.Empty }).ToList();
        }

        private HashSet<ulong> GetAuthorIDsForCodeLock(ulong playerId, CodeLock codeLock)
        {
            var sharePlayers = new HashSet<ulong>();
            var parentEntity = codeLock.GetParentEntity();
            if (parentEntity == null)
            {
                return sharePlayers;
            }
            var shareData = GetShareData(playerId, true);

            var teamsShare = shareData.GetShareEntry(ShareType.Teams);
            if (teamsShare.enabled && CanShareLockedEntity(parentEntity, teamsShare.codeLock))
            {
                var teamMembers = GetTeamMembers(playerId);
                if (teamMembers != null)
                {
                    foreach (var member in teamMembers)
                    {
                        sharePlayers.Add(member);
                    }
                }
            }
            var friendsShare = shareData.GetShareEntry(ShareType.Friends);
            if (friendsShare.enabled && CanShareLockedEntity(parentEntity, friendsShare.codeLock))
            {
                var friends = GetFriends(playerId);
                if (friends != null)
                {
                    foreach (var friend in friends)
                    {
                        sharePlayers.Add(friend);
                    }
                }
            }
            var clansShare = shareData.GetShareEntry(ShareType.Clans);
            if (clansShare.enabled && CanShareLockedEntity(parentEntity, clansShare.codeLock))
            {
                var clanMembers = GetClanMembers(playerId);
                if (clanMembers != null)
                {
                    foreach (var member in clanMembers)
                    {
                        sharePlayers.Add(member);
                    }
                }
            }
            return sharePlayers;
        }

        private HashSet<ulong> GetAuthIds(ulong playerId, AutoAuthType autoAuthType)
        {
            var sharePlayers = new HashSet<ulong> { playerId };
            var shareData = GetShareData(playerId, true);

            var teamsShare = shareData.GetShareEntry(ShareType.Teams);
            if (teamsShare.enabled && (autoAuthType == AutoAuthType.Turret ? teamsShare.turret : teamsShare.cupboard))
            {
                var teamMembers = GetTeamMembers(playerId);
                if (teamMembers != null)
                {
                    foreach (var member in teamMembers)
                    {
                        sharePlayers.Add(member);
                    }
                }
            }
            var friendsShare = shareData.GetShareEntry(ShareType.Friends);
            if (friendsShare.enabled && (autoAuthType == AutoAuthType.Turret ? friendsShare.turret : friendsShare.cupboard))
            {
                var friends = GetFriends(playerId);
                if (friends != null)
                {
                    foreach (var friend in friends)
                    {
                        sharePlayers.Add(friend);
                    }
                }
            }
            var clansShare = shareData.GetShareEntry(ShareType.Clans);
            if (clansShare.enabled && (autoAuthType == AutoAuthType.Turret ? clansShare.turret : clansShare.cupboard))
            {
                var clanMembers = GetClanMembers(playerId);
                if (clanMembers != null)
                {
                    foreach (var member in clanMembers)
                    {
                        sharePlayers.Add(member);
                    }
                }
            }
            return sharePlayers;
        }

        private bool CanSharingLock(BaseLock baseLock, BaseEntity parentEntity, StoredData.ShareData shareData, ShareType shareType, ulong ownerId, ulong playerId)
        {
            var shareEntry = shareData.GetShareEntry(shareType);
            if (shareEntry.enabled && AreFriends(shareType, ownerId, playerId))
            {
                if (baseLock is KeyLock)
                {
                    return CanShareLockedEntity(parentEntity, shareEntry.keyLock);
                }
                var codeLock = baseLock as CodeLock;
                if (codeLock != null && CanShareLockedEntity(parentEntity, shareEntry.codeLock))
                {
                    SendUnlockedEffect(codeLock);
                    return true;
                }
            }
            return false;
        }

        private IEnumerable<ShareType> GetAvailableTypes()
        {
            if (IsShareTypeEnabled(ShareType.Teams))
            {
                yield return ShareType.Teams;
            }
            if (IsShareTypeEnabled(ShareType.Friends))
            {
                yield return ShareType.Friends;
            }
            if (IsShareTypeEnabled(ShareType.Clans))
            {
                yield return ShareType.Clans;
            }
        }

        private bool IsShareTypeEnabled(ShareType shareType)
        {
            var shareSettings = configData.GetShareSettings(shareType);
            if (!shareSettings.Enabled)
            {
                return false;
            }
            switch (shareType)
            {
                case ShareType.Teams:
                    return RelationshipManager.TeamsEnabled();
                case ShareType.Friends:
                    return Friends != null;
                case ShareType.Clans:
                    return Clans != null;
            }
            return false;
        }

        private bool AreFriends(ShareType shareType, ulong ownerId, ulong playerId)
        {
            switch (shareType)
            {
                case ShareType.Teams:
                    return SameTeam(ownerId, playerId);
                case ShareType.Friends:
                    return HasFriend(ownerId, playerId);
                case ShareType.Clans:
                    return SameClan(ownerId, playerId);
            }
            return false;
        }

        #region Data

        private StoredData.ShareData _defaultData;

        private StoredData.ShareData DefaultData => _defaultData ?? (_defaultData = CreateDefaultData());

        private StoredData.ShareData GetShareData(ulong playerId, bool readOnly = false)
        {
            StoredData.ShareData shareData;
            if (!storedData.playerShareData.TryGetValue(playerId, out shareData))
            {
                if (readOnly)
                {
                    return DefaultData;
                }

                shareData = CreateDefaultData();
                storedData.playerShareData.Add(playerId, shareData);
            }
            return shareData;
        }

        private StoredData.ShareData CreateDefaultData()
        {
            return new StoredData.ShareData
            {
                teamsShare = CreateShareEntry(ShareType.Teams),
                friendsShare = CreateShareEntry(ShareType.Friends),
                clansShare = CreateShareEntry(ShareType.Clans)
            };
        }

        private void UpdateData()
        {
            foreach (var shareData in storedData.playerShareData.Values)
            {
                CheckShareData(shareData, ShareType.Teams);
                CheckShareData(shareData, ShareType.Friends);
                CheckShareData(shareData, ShareType.Clans);
            }
            SaveData();
        }

        private StoredData.ShareEntry CreateShareEntry(ShareType shareType)
        {
            var defaultSettings = configData.GetDefaultShareSettings(shareType);
            var shareEntry = new StoredData.ShareEntry
            {
                enabled = defaultSettings.Enabled,
                turret = defaultSettings.ShareTurret,
                cupboard = defaultSettings.ShareCupboard,
                keyLock = new StoredData.LockShareEntry
                {
                    enabled = defaultSettings.KeyLock.Enabled,
                    door = defaultSettings.KeyLock.ShareDoor,
                    box = defaultSettings.KeyLock.ShareBox,
                    other = defaultSettings.KeyLock.ShareOtherEntity
                },
                codeLock = new StoredData.LockShareEntry
                {
                    enabled = defaultSettings.CodeLock.Enabled,
                    door = defaultSettings.CodeLock.ShareDoor,
                    box = defaultSettings.CodeLock.ShareBox,
                    other = defaultSettings.CodeLock.ShareOtherEntity
                }
            };
            CheckShareData(shareEntry, configData.GetShareSettings(shareType));
            return shareEntry;
        }

        private void CheckShareData(StoredData.ShareData shareData, ShareType shareType)
        {
            var shareSettings = configData.GetShareSettings(shareType);
            var shareEntry = shareData.GetShareEntry(shareType);
            CheckShareData(shareEntry, shareSettings);
        }

        #endregion Data

        #region Conflict Resolution

        private bool IsBankBox(BaseNetworkable entity)
        {
            return Bank != null && Bank.Call<bool>("IsBankBox", entity);
        }

        #endregion Conflict Resolution

        #endregion Methods

        #region External Plugins

        #region Teams

        #region Hooks

        private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam playerTeam, BasePlayer player)
        {
            NextTick(() =>
            {
                if (playerTeam == null || player == null)
                {
                    return;
                }
                if (playerTeam.members.Contains(player.userID))
                {
                    UpdateTeamAuthList(playerTeam.members);
                }
            });
        }

        private void OnTeamLeave(RelationshipManager.PlayerTeam playerTeam, BasePlayer player)
        {
            NextTick(() =>
            {
                if (playerTeam == null || player == null)
                {
                    return;
                }
                if (!playerTeam.members.Contains(player.userID))
                {
                    var teamMembers = new List<ulong>(playerTeam.members) { player.userID };
                    UpdateTeamAuthList(teamMembers);
                }
            });
        }

        private void OnTeamKick(RelationshipManager.PlayerTeam playerTeam, BasePlayer leader, ulong target)
        {
            NextTick(() =>
            {
                if (playerTeam == null)
                {
                    return;
                }
                if (!playerTeam.members.Contains(target))
                {
                    var teamMembers = new List<ulong>(playerTeam.members) { target };
                    UpdateTeamAuthList(teamMembers);
                }
            });
        }

        private void OnTeamDisbanded(RelationshipManager.PlayerTeam playerTeam)
        {
            if (playerTeam == null)
            {
                return;
            }
            UpdateTeamAuthList(playerTeam.members);
        }

        #endregion Hooks

        private void UpdateTeamAuthList(List<ulong> teamMembers)
        {
            if (teamMembers.Count <= 0)
            {
                return;
            }
            foreach (var member in teamMembers)
            {
                UpdateAuthList(member, AutoAuthType.All);
            }
        }

        private static IEnumerable<ulong> GetTeamMembers(ulong playerId)
        {
            if (!RelationshipManager.TeamsEnabled())
            {
                return null;
            }
            var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
            return playerTeam?.members;
        }

        private static bool SameTeam(ulong playerId, ulong friendId)
        {
            if (!RelationshipManager.TeamsEnabled())
            {
                return false;
            }
            var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
            if (playerTeam == null)
            {
                return false;
            }
            var friendTeam = RelationshipManager.ServerInstance.FindPlayersTeam(friendId);
            if (friendTeam == null)
            {
                return false;
            }
            return playerTeam == friendTeam;
        }

        #endregion Teams

        #region Friends

        #region Hooks

        private void OnFriendAdded(string playerId, string friendId)
        {
            UpdateFriendAuthList(playerId, friendId);
        }

        private void OnFriendRemoved(string playerId, string friendId)
        {
            UpdateFriendAuthList(playerId, friendId);
        }

        #endregion Hooks

        private void UpdateFriendAuthList(string playerId, string friendId)
        {
            UpdateAuthList(Convert.ToUInt64(playerId), AutoAuthType.All);
            UpdateAuthList(Convert.ToUInt64(friendId), AutoAuthType.All);
        }

        private IEnumerable<ulong> GetFriends(ulong playerId)
        {
            if (Friends == null)
            {
                return null;
            }
            var friends = Friends.Call("GetFriends", playerId) as ulong[];
            return friends;
        }

        private bool HasFriend(ulong playerId, ulong friendId)
        {
            if (Friends == null)
            {
                return false;
            }
            var hasFriend = Friends.Call("HasFriend", playerId, friendId);
            return hasFriend is bool && (bool)hasFriend;
        }

        #endregion Friends

        #region Clans

        #region Hooks

        private void OnClanDestroy(string clanName)
        {
            UpdateClanAuthList(clanName);
        }

        private void OnClanUpdate(string clanName)
        {
            UpdateClanAuthList(clanName);
        }

        #region Clans Reborn Hooks

        private void OnClanMemberGone(string playerId, List<string> memberUserIDs)
        {
            UpdateAuthList(Convert.ToUInt64(playerId), AutoAuthType.All);
        }

        #endregion Clans Reborn Hooks

        #endregion Hooks

        private void UpdateClanAuthList(string clanName)
        {
            var clanMembers = GetClanMembers(clanName);
            if (clanMembers != null)
            {
                foreach (var member in clanMembers)
                {
                    UpdateAuthList(member, AutoAuthType.All);
                }
            }
        }

        private IEnumerable<ulong> GetClanMembers(ulong playerId)
        {
            if (Clans == null)
            {
                return null;
            }
            //Clans Reborn
            var members = Clans.Call("GetClanMembers", playerId) as List<string>;
            if (members != null)
            {
                return members.Select(x => Convert.ToUInt64(x));
            }
            //Clans
            var clanName = Clans.Call("GetClanOf", playerId) as string;
            return clanName != null ? GetClanMembers(clanName) : null;
        }

        private IEnumerable<ulong> GetClanMembers(string clanName)
        {
            if (Clans == null)
            {
                return null;
            }
            var clan = Clans.Call("GetClan", clanName) as JObject;
            var members = clan?.GetValue("members") as JArray;
            return members?.Select(Convert.ToUInt64);
        }

        private bool SameClan(ulong playerId, ulong friendId)
        {
            if (Clans == null)
            {
                return false;
            }
            //Clans and Clans Reborn
            var isMember = Clans.Call("IsClanMember", playerId.ToString(), friendId.ToString());
            if (isMember != null)
            {
                return (bool)isMember;
            }
            //Rust:IO Clans
            var playerClan = Clans.Call("GetClanOf", playerId);
            if (playerClan == null)
            {
                return false;
            }
            var friendClan = Clans.Call("GetClanOf", friendId);
            if (friendClan == null)
            {
                return false;
            }
            return (string)playerClan == (string)friendClan;
        }

        #endregion Clans

        #endregion External Plugins

        #region UI

        private const string UINAME_MAIN = "AutoAuthUI_Main";
        private const string UINAME_MENU = "AutoAuthUI_Menu";

        private void CreateMainUI(BasePlayer player)
        {
            var container = new CuiElementContainer();
            container.Add(new CuiPanel
            {
                Image = { Color = "0 0 0 0.6" },
                RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-390 -200", OffsetMax = "390 260" },
                CursorEnabled = true
            }, "Hud", UINAME_MAIN);
            var titlePanel = container.Add(new CuiPanel
            {
                Image = { Color = "0.31 0.88 0.71 1" },
                RectTransform = { AnchorMin = "0 0.912", AnchorMax = "0.998 1" }
            }, UINAME_MAIN);
            container.Add(new CuiElement
            {
                Parent = titlePanel,
                Components =
                {
                    new CuiTextComponent { Text = Lang("UI_Title", player.UserIDString), FontSize = 24, Align = TextAnchor.MiddleCenter, Color = "1 0 0 1" },
                    new CuiOutlineComponent { Distance = "0.5 0.5", Color = "1 1 1 1" },
                    new CuiRectTransformComponent { AnchorMin = "0.2 0", AnchorMax = "0.8 1" }
                }
            });
            container.Add(new CuiButton
            {
                Button = { Color = "0.95 0.1 0.1 0.95", Close = UINAME_MAIN },
                Text = { Text = "X", Align = TextAnchor.MiddleCenter, Color = "0 0 0 1", FontSize = 22 },
                RectTransform = { AnchorMin = "0.915 0", AnchorMax = "1 0.99" }
            }, titlePanel);
            container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.4" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.908" }
            }, UINAME_MAIN, UINAME_MENU);
            CuiHelper.DestroyUi(player, UINAME_MAIN);
            CuiHelper.AddUi(player, container);
            var shareData = GetShareData(player.userID, true);
            UpdateMenuUI(player, shareData);
        }

        private void UpdateMenuUI(BasePlayer player, StoredData.ShareData shareData, ShareType shareType = ShareType.None)
        {
            if (player == null)
            {
                return;
            }
            var availableTypes = GetAvailableTypes();
            var total = availableTypes.Count();
            if (total <= 0)
            {
                return;
            }

            var i = 0;
            var container = new CuiElementContainer();

            #region Teams UI

            if (availableTypes.Contains(ShareType.Teams))
            {
                if (shareType == ShareType.None || shareType == ShareType.Teams)
                {
                    var anchors = GetMenuSubAnchors(i, total);
                    CuiHelper.DestroyUi(player, UINAME_MENU + ShareType.Teams);
                    CreateMenuSubUI(ref container, shareData, player.UserIDString, ShareType.Teams, $"{anchors[0]} 0.03", $"{anchors[1]} 0.97");
                }
                i++;
            }

            #endregion Teams UI

            #region Friends UI

            if (availableTypes.Contains(ShareType.Friends))
            {
                if (shareType == ShareType.None || shareType == ShareType.Friends)
                {
                    var anchors = GetMenuSubAnchors(i, total);
                    CuiHelper.DestroyUi(player, UINAME_MENU + ShareType.Friends);
                    CreateMenuSubUI(ref container, shareData, player.UserIDString, ShareType.Friends, $"{anchors[0]} 0.03", $"{anchors[1]} 0.97");
                }
                i++;
            }

            #endregion Friends UI

            #region Clans UI

            if (availableTypes.Contains(ShareType.Clans))
            {
                if (shareType == ShareType.None || shareType == ShareType.Clans)
                {
                    var anchors = GetMenuSubAnchors(i, total);
                    CuiHelper.DestroyUi(player, UINAME_MENU + ShareType.Clans);
                    CreateMenuSubUI(ref container, shareData, player.UserIDString, ShareType.Clans, $"{anchors[0]} 0.03", $"{anchors[1]} 0.97");
                }
            }

            #endregion Clans UI

            CuiHelper.AddUi(player, container);
        }

        private void CreateMenuSubUI(ref CuiElementContainer container, StoredData.ShareData shareData, string playerId, ShareType shareType, string anchorMin, string anchorMax)
        {
            var panelName = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.5" },
                RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax }
            }, UINAME_MENU, UINAME_MENU + shareType);
            var titlePanel = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.5" },
                RectTransform = { AnchorMin = "0 0.9", AnchorMax = "1 1" }
            }, panelName);
            container.Add(new CuiLabel
            {
                Text = { Color = "1 0.5 0 1", FontSize = 18, Align = TextAnchor.MiddleCenter, Text = Lang("UI_SubTitle", playerId, Lang("UI_" + shareType, playerId)) },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
            }, titlePanel);

            var contentPanel = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.55" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.895" }
            }, panelName);

            var i = 0;
            const float entrySize = 0.08f;
            const float spacingY = 0.012f;

            var shareEntry = shareData.GetShareEntry(shareType);
            var commandPrefix = $"AutoAuthUI {shareType} ";
            var enabledMsg = Lang("Enabled", playerId);
            var disabledMsg = Lang("Disabled", playerId);

            var anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix, Lang("UI_SubShare", playerId, Lang("UI_" + shareType, playerId)),
                             shareEntry.enabled ? enabledMsg : disabledMsg, $"0 {anchors[0]}",
                             $"0.995 {anchors[1]}");

            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "Cupboard", Lang("UI_SubCupboard", playerId),
                             shareEntry.cupboard ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");

            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "Turret", Lang("UI_SubTurret", playerId),
                             shareEntry.turret ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");

            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock", Lang("UI_SubKeyLock", playerId),
                             shareEntry.keyLock.enabled ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");

            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock Door", Lang("UI_SubKeyLockDoor", playerId),
                             shareEntry.keyLock.door ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock Box", Lang("UI_SubKeyLockBox", playerId),
                             shareEntry.keyLock.box ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock Other", Lang("UI_SubKeyLockOther", playerId),
                             shareEntry.keyLock.other ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");

            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock", Lang("UI_SubCodeLock", playerId),
                             shareEntry.codeLock.enabled ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock Door", Lang("UI_SubCodeLockDoor", playerId),
                             shareEntry.codeLock.door ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock Box", Lang("UI_SubCodeLockBox", playerId),
                             shareEntry.codeLock.box ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
            anchors = GetEntryAnchors(i++, entrySize, spacingY);
            CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock Other", Lang("UI_SubCodeLockOther", playerId),
                             shareEntry.codeLock.other ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
        }

        private static void CreateEntrySubUI(ref CuiElementContainer container, string parentName, string command, string leftText, string rightText, string anchorMin, string anchorMax)
        {
            var panelName = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.6" },
                RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax }
            }, parentName);
            container.Add(new CuiLabel
            {
                Text = { Color = "0 1 1 1", FontSize = 12, Align = TextAnchor.MiddleLeft, Text = leftText },
                RectTransform = { AnchorMin = "0.04 0", AnchorMax = "0.68 1" }
            }, panelName);
            container.Add(new CuiButton
            {
                Button = { Color = "0 0 0 0.7", Command = command },
                Text = { Text = rightText, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FontSize = 12 },
                RectTransform = { AnchorMin = "0.7 0.2", AnchorMax = "0.985 0.8" }
            }, panelName);
        }

        private static float[] GetEntryAnchors(int i, float entrySize, float spacingY)
        {
            return new[] { 1f - (i + 1) * entrySize - i * spacingY, 1f - i * (entrySize + spacingY) };
        }

        private static float[] GetMenuSubAnchors(int i, int total)
        {
            switch (total)
            {
                case 1:
                    return new[] { 0.32f, 0.68f };
                case 2:
                    return i == 0 ? new[] { 0.15f, 0.48f } : new[] { 0.52f, 0.85f };
                case 3:
                    switch (i)
                    {
                        case 0:
                            return new[] { 0.01f, 0.33f };
                        case 1:
                            return new[] { 0.34f, 0.66f };
                        default:
                            return new[] { 0.67f, 0.99f };
                    }

                default:
                    return null;
            }
        }

        private static void DestroyUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, UINAME_MAIN);
        }

        #endregion UI

        #region Chat Commands

        private void CmdAutoAuth(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
            {
                Print(player, Lang("NotAllowed", player.UserIDString));
                return;
            }
            var shareData = GetShareData(player.userID);
            if (args == null || args.Length == 0)
            {
                var availableTypes = GetAvailableTypes();
  
// ... [Code preview truncated due to length. Full source in attached file] ...

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