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

FREE Friends : 4.0.3 4.0.3

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core.Plugins;
using ConVar;
using Oxide.Game.Rust;
using System;
using ProtoBuf;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins {
    /*Плагин был разыгран в дискорде https://discord.gg/8CWJadmA5w */
    [Info("Friends", "https://discord.gg/8CWJadmA5w", "4.0.3")]
    [Description("Friends system rust")]
    public class Friends : RustPlugin {
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["TEAM_FOUND"]
                = "Player not found", ["TEAM_FOUND_MULTIPLE"] = "Multiple players found with this name\n{0}", ["TEAM_SENDINVITETILE"] = "TEAM SYSTEM", ["TEAM_SENDINVITE"] = "Player <color=#89f5bf>{0}</color> has sent you a team invitation", ["TEAM_NULL"] = "You don't have a team yet.\nTo create one, press (<color=#3eb2f0>TAB</color>)", ["TEAM_NULLNICKNAME"] = "You didn't enter a player's name!", ["TEAM_NULLNICKNAMENULL"] = "You can't add yourself to the team", ["TEAM_ISCOMMAND"] = "Player <color=#89f5bf>{0}</color> is already in a team", ["TEAM_MAXTEAMSIZE"] = "There are no available spots in the team", ["TEAM_TIMENULL"] = "Your invitation has been declined, the response time has expired", ["TEAM_TIMENULS"] = "Invitation from <color=#89f5bf>{0}</color> has been cancelled, the response time has expired", ["TEAM_IVITE"] = "You have successfully sent a team invitation to player <color=#89f5bf>{0}</color>", ["TEAM_INVITETARGET"] = "Player <color=#89f5bf>{0}</color> has invited you to their team.\nTo accept or decline the invitation, press (<color=#3eb2f0>TAB</color>)", ["TEAM_CUPBOARCLEAR"] = "You have kicked a team member.\nThey have been automatically removed from the cupboard access list!", ["TEAM_CUPBOARADD"] = "Your new team member (<color=#89f5bf>{0}</color>) has been successfully authorized in cupboards!", ["TEAM_CUPBOARADDLEAVE"] = "You have left the team and have been deauthorized from the cupboards", ["TEAM_FFON"] = "You've <color=#64f578>enabled</color> friendly fire", ["TEAM_FFOFF"] = "You've <color=#f03e3e>disabled</color> friendly fire", ["TEAM_FFATTACK"] = "Player: <color=#89f5bf>{0}</color> is your friend!\nYou can't <color=#ff9696>kill</color> them\nTo enable friendly fire, type /team ff", ["TEAM_INFO"] = "To create a team, press (<color=#3eb2f0>TAB</color>) and select 'Create Team'.\n" + "Invite a player to the team via (<color=#3eb2f0>TAB</color>) or by the command:\n" + "1.<color=#46bec2>/Team add nickname</color> - Invite to team at a distance\n" + "2.<color=#46bec2>/team ff</color> - Enables or disables friendly fire\n" + "When adding a player to the team, they will automatically be added to <color=#89f5af>Turrets</color>, <color=#89f5af>Lockers</color>, <color=#89f5af>Doors</color>." + "\nWhen removing from the team, the player's access will be <color=#ff9696>revoked</color>.", ["TEAM_LOG_1"] = "Player {0} created team #{1}", ["TEAM_LOG_2"] = "Player {0} accepted an invitation to team #{1} from player {2}\nCurrent team member list:\n{3}", ["TEAM_LOG_3"] = "Player {0} kicked player {2} from team #{1}\nCurrent team member list:\n{3}", ["TEAM_LOG_4"] = "The leader of team #{0} left.The new team leader is {1}\nCurrent team member list:\n{2}", ["TEAM_LOG_5"] = "Player {0} left team #{1} of player {2}\nCurrent team member list:\n{3}", ["TEAM_LOG_6"] = "Team #{0} of player {1} has been disbanded",
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["TEAM_FOUND"]
                = "Игрок не обнаружен", ["TEAM_FOUND_MULTIPLE"] = "Обнаружено несколько игроков с таким именем\n{0}", ["TEAM_SENDINVITETILE"] = "СИСТЕМА КОМАНДЫ", ["TEAM_SENDINVITE"] = "Игрок <color=#89f5bf>{0}</color> предлагает вам присоединиться к команде", ["TEAM_NULL"] = "У вас пока нет команды.\nЧтобы создать команду, нажмите (<color=#3eb2f0>TAB</color>)", ["TEAM_NULLNICKNAME"] = "Вы не ввели имя игрока!", ["TEAM_NULLNICKNAMENULL"] = "Вы не можете добавить себя в команду", ["TEAM_ISCOMMAND"] = "Игрок <color=#89f5bf>{0}</color> уже является членом команды", ["TEAM_MAXTEAMSIZE"] = "В команде нет места для новых участников", ["TEAM_TIMENULL"] = "Ваше приглашение отклонено, время на ответ истекло", ["TEAM_TIMENULS"] = "Приглашение от <color=#89f5bf>{0}</color> отменено, время на ответ истекло", ["TEAM_IVITE"] = "Вы успешно отправили приглашение в команду игроку <color=#89f5bf>{0}</color>", ["TEAM_INVITETARGET"] = "Игрок <color=#89f5bf>{0}</color> пригласил вас в команду.\nЧтобы принять или отклонить приглашение, нажмите (<color=#3eb2f0>TAB</color>)", ["TEAM_CUPBOARCLEAR"] = "Вы исключили участника из команды.\nОн был автоматически удален из доступа к шкафам!", ["TEAM_CUPBOARADD"] = "Ваш новый член команды (<color=#89f5bf>{0}</color>) успешно добавлен в доступ к шкафам!", ["TEAM_CUPBOARADDLEAVE"] = "Вы покинули команду и были удалены из доступа к шкафам", ["TEAM_FFON"] = "Вы <color=#64f578>включили</color> возможность нанесения урона друзьям", ["TEAM_FFOFF"] = "Вы <color=#f03e3e>отключили</color> возможность нанесения урона друзьям", ["TEAM_FFATTACK"] = "Игрок <color=#89f5bf>{0}</color> - ваш друг!\nВы не можете его <color=#ff9696>атаковать</color>\nЧтобы включить урон по друзьям, напишите /team ff", ["TEAM_INFO"] = "Чтобы создать команду, нажмите (<color=#3eb2f0>TAB</color>) и выберите 'Создать команду'.n" + "Пригласить игрока в команду можно через (<color=#3eb2f0>TAB</color>) или командой:\n" + "1.<color=#46bec2>/Team add ник</color> - Пригласить в команду на расстоянии\n" + "2.<color=#46bec2>/team ff</color> - Включает и выключает возможность нанесения урона друзьям\n" + "При добавлении игрока в команду, он будет автоматически добавлен в <color=#89f5af>Турели</color>, <color=#89f5af>шкафы</color>, <color=#89f5af>двери</color>." + "\nПри исключении из команды, доступ игрока будет <color=#ff9696>отменен</color>.", ["TEAM_LOG_1"] = "Игрок {0} основал команду #{1}", ["TEAM_LOG_2"] = "Игрок {0} присоединился к команде #{1} по приглашению от {2}\nАктуальный список участников команды:\n{3}", ["TEAM_LOG_3"] = "Игрок {0} исключил из команды #{1} игрока {2}\nАктуальный список участников команды:\n{3}", ["TEAM_LOG_4"] = "Лидер команды #{0} покинул ее.Новым лидером становится {1}\nАктуальный список участников команды:\n{2}", ["TEAM_LOG_5"] = "Игрок {0} покинул команду #{1} под управлением игрока {2}\nАктуальный список участников команды:\n{3}", ["TEAM_LOG_6"] = "Команда #{0}, возглавляемая игроком {1}, расформирована",
            }
            , this, "ru");
        }
        private List<PlayerNameID> GetTeamMembers(ulong ownerId) {
            if (!RelationshipManager.TeamsEnabled()) return null;
            RelationshipManager.PlayerTeam playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(ownerId);
            List<PlayerNameID> playerNameIDList = new List<PlayerNameID>();
            if (playerTeam == null) {
                playerNameIDList.Add(new PlayerNameID {
                    userid = ownerId, username = RustCore.FindPlayerById(ownerId)?.displayName ?? string.Empty
                }
                );
            }
            else {
                if (playerTeam.members != null) {
                    foreach (ulong userid in playerTeam.members) {
                        string username = RustCore.FindPlayerById(userid)?.displayName ?? string.Empty;
                        playerNameIDList.Add(new PlayerNameID {
                            userid = userid, username = username
                        }
                        );
                    }
                }
            }
            return playerNameIDList;
        }
        private object CanUseLockedEntity(BasePlayer player, KeyLock keyLock) {
            if (player == null || keyLock == null || !keyLock.IsLocked()) return null;
            BaseEntity parentEntity = keyLock.GetParentEntity();
            ulong ownerID = keyLock.OwnerID.IsSteamId() ? keyLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
            if (!ownerID.IsSteamId() || ownerID == player.userID) return null;
            if (!HasFriend(ownerID, player.userID)) return null;
            return true;
        }
        private const bool RU = true;
        private string[] IsFriendOf(string playerS) {
            ulong playerId;
            if (ulong.TryParse(playerS, out playerId)) {
                ulong[] friendIds = IsFriendOf(playerId);
                string[] friendStrings = new string[friendIds.Length];
                for (int i = 0; i < friendIds.Length; i++) {
                    friendStrings[i] = friendIds[i].ToString();
                }
                return friendStrings;
            }
            return new string[] {
            }
            ;
        }
        private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) => TruePVE != null ? null : CanEntityTakeDamage(entity, info);
        private class Configuration {
            [JsonProperty(PropertyName = RU ? "Префикс в чате (IQChat)" : "Chat prefix (IQChat)")]
            public string ChatPrefix = "<color=#5cd65070>[Friends]</color>\n";
            [JsonProperty(PropertyName = RU ? "Активировать авторизацию друзей для ключевых замков?" : "Enable friend authorization for key locks?")]
            public bool KeyLockAuthUse = true;
            [JsonProperty(PropertyName = RU ? "Время ожидания принятия приглашения в команду (в секундах)" : "Time to accept team invite (in seconds)")]
            public float InviteAcceptTime = 20f;
            [JsonProperty(PropertyName = RU ? "Метод авторизации для кодовых замков (guestPlayers - гостевая авторизация, whitelistPlayers - полная авторизация)" : "Authorization method for code locks (guestPlayers - guest authorization, whitelistPlayers - full authorization)")]
            public string MethodCodeLockAuthUse = "guestPlayers";
            [JsonProperty(PropertyName = RU ? "Активировать авторизацию друзей для турелей?" : "Enable friend authorization for turrets?")]
            public bool TurretAuthUse = true;
            [JsonProperty(PropertyName = RU ? "Активировать авторизацию друзей для кодовых замков?" : "Enable friend authorization for code locks?")]
            public bool CodeLockAuthUse = true;
            [JsonProperty(PropertyName = RU ? "Включить систему логирования ?" : "Enable logging system ?")]
            public bool LoggerUse = false;
            [JsonProperty(PropertyName = RU ? "Активировать авторизацию друзей для шкафов?" : "Enable friend authorization for cupboards?")]
            public bool CupboardAuthUse = true;
            [JsonProperty(PropertyName = RU ? "Максимальное число друзей" : "Maximum number of friends")]
            public int MaxTeamSize = 3;
            [JsonProperty(PropertyName = RU ? "Команды чата" : "Chat commands")]
            public string[] ChatCommands = {
                "team", "ff", "friend"
            }
            ;
            [JsonProperty(PropertyName = RU ? "Активировать авторизацию друзей для ПВО?" : "Enable friend authorization for SAM sites?")]
            public bool SamSiteAuthUse = true;
        }
        [PluginReference]
        private readonly Plugin IQChat, TruePVE, EventHelper, Battles, Duel, Duelist, ArenaTournament;
        private object OnSamSiteTarget(SamSite entity, BaseCombatEntity target) {
            BaseVehicle vehicle = target as BaseVehicle;
            if (ReferenceEquals(vehicle, null) || entity.OwnerID <= 0) return null;
            BasePlayer player = vehicle.GetDriver();
            if (player == null) return null;
            if(player.userID == entity.OwnerID) return false;
            if (HasFriend(entity.OwnerID, player.userID)) return false;
            return null;
        }
        private bool WasFriend(ulong player, ulong target) => HasFriend(player, target);
        private void Unsubscribes() {
            foreach (string hook in _hooks) {
                Unsubscribe(hook);
            }
        }
        private bool WereFriendsS(string playerS, string friendS) => HasFriend(ulong.Parse(playerS), ulong.Parse(friendS));
        private readonly Dictionary<ulong, List<BuildingPrivlidge>> _playerCupboardsCache = new Dictionary<ulong, List<BuildingPrivlidge>>();
        private void RemoveCupboardCache(BuildingPrivlidge buildingPrivlidge) {
            if (buildingPrivlidge == null || !buildingPrivlidge.OwnerID.IsSteamId()) return;
            List<BuildingPrivlidge> buildingPrivlidges;
            if (_playerCupboardsCache.TryGetValue(buildingPrivlidge.OwnerID, out buildingPrivlidges) && buildingPrivlidges.Contains(buildingPrivlidge)) buildingPrivlidges.Remove(buildingPrivlidge);
        }
        private Configuration _config;
        private bool HadFriends(string playerS, string targetS) => HasFriend(ulong.Parse(playerS), ulong.Parse(targetS));
        private void LogMessage(string message) {
            if(!_config.LoggerUse) return;
            _logQueue.Enqueue(new LogEntry("history", GetCurrentTimestamp(), message));
            while(_logQueue.Count > 0) {
                if (AttemptWriteToLogFile(_logQueue.Peek().Prefix, _logQueue.Peek().Timestamp, _logQueue.Peek().Message)) _logQueue.Dequeue();
                else break;
            }
        }
        private bool WereFriends(ulong player, ulong target) => HasFriend(player, target);
        private void LoadData() => _ffTeam = Interface.GetMod().DataFileSystem.ReadObject<Dictionary<ulong, bool>>("FriendlyFireData");
        private void UpdateLockAuth(List<CodeLock> codeLocks, ulong ownerId) {
            List<PlayerNameID> team = GetTeamMembers(ownerId);
            if (team == null || codeLocks == null || codeLocks.Count == 0) return;
            foreach (CodeLock codeLock in codeLocks) {
                if (codeLock.IsDestroyed) continue;
                ReAuthTeamInCodeLock(team, codeLock, ownerId);
            }
        }
        private bool AreFriends(string playerS, string friendS) {
            if (string.IsNullOrEmpty(playerS) || string.IsNullOrEmpty(friendS)) return false;
            ulong playerId, friendId;
            if (ulong.TryParse(playerS, out playerId) && ulong.TryParse(friendS, out friendId)) {
                return AreFriends(playerId, friendId);
            }
            return false;
        }
        private string[] GetFriendList(string playerS) {
            ulong playerId;
            if (ulong.TryParse(playerS, out playerId)) {
                return GetFriendList(playerId);
            }
            return new string[] {
            }
            ;
        }
        public static StringBuilder StringBuilderInstance;
        private void OnEntitySpawned(CodeLock codeLock) => AddCodeLockCache(codeLock, true);
        private void OnTeamCreated(BasePlayer player, RelationshipManager.PlayerTeam team) {
            LogMessage(GetLang("TEAM_LOG_1", null, player.userID, team.teamID));
        }
        private bool AreFriends(ulong playerId, ulong friendId) {
            RelationshipManager.PlayerTeam playerTeam, friendTeam;
            if (RelationshipManager.ServerInstance.playerToTeam.TryGetValue(playerId, out playerTeam) && RelationshipManager.ServerInstance.playerToTeam.TryGetValue(friendId, out friendTeam)) {
                return playerTeam.members.Contains(friendId) && friendTeam.members.Contains(playerId);
            }
            return false;
        }
        private Dictionary<ulong, bool> _ffTeam = new Dictionary<ulong, bool>();
        private class LogEntry {
            public string Prefix;
            public string Timestamp;
            public string Message;
            public LogEntry(string prefix, string timestamp, string message) {
                this.Prefix = prefix;
                this.Timestamp = timestamp;
                this.Message = message;
            }
        }
        private void SaveData() => Interface.GetMod().DataFileSystem.WriteObject("FriendlyFireData", _ffTeam);
        private bool HadFriend(ulong player, ulong target) => HasFriend(player, target);
        private void OnEntityKill(CodeLock codeLock) => RemoveCodeLockCache(codeLock);
        private bool HasFriend(ulong playerId, ulong friendId) {
            RelationshipManager.PlayerTeam team;
            if (RelationshipManager.ServerInstance.playerToTeam.TryGetValue(playerId, out team)) {
                return team.members.Contains(friendId);
            }
            return false;
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) LoadDefaultConfig();
                ValidateConfig();
                SaveConfig();
            }
            catch (JsonException ex) {
                Debug.LogException(ex);
                LoadDefaultConfig();
            }
        }
        private string GetLang(string langKey, string userID = null, params object[] args) {
            StringBuilderInstance.Clear();
            if (args != null) {
                StringBuilderInstance.AppendFormat(lang.GetMessage(langKey, this, userID), args);
                return StringBuilderInstance.ToString();
            }
            return lang.GetMessage(langKey, this, userID);
        }
        private void ReAuthTeamInCodeLock(List<PlayerNameID> teamMember, CodeLock codeLock, ulong ownerId) {
            if (teamMember == null) return;
            bool isGuest = _config.MethodCodeLockAuthUse == "guestPlayers";
            List<ulong> authList = isGuest ? codeLock.guestPlayers : codeLock.whitelistPlayers;
            if (isGuest) authList.Clear();
            else authList.RemoveAll(owner => owner != ownerId);
            foreach (PlayerNameID friend in teamMember) authList.Add(friend.userid);
            codeLock.SendNetworkUpdate();
        }
        private bool IsDuel(UInt64 userID) {
            object playerId = ObjectCache.Get(userID);
            BasePlayer player = null;
            if(Duel != null || Duelist != null) player = BasePlayer.FindByID(userID);
            if (EventHelper != null) {
                object result = EventHelper.Call("EMAtEvent", playerId);
                if (result is bool && ((bool) result) == true) return true;
            }
            if (Battles != null && Battles.Call<bool>("IsPlayerOnBattle", playerId)) return true;
            if (Duel != null && Duel.Call<bool>("IsPlayerOnActiveDuel", player)) return true;
            if (Duelist != null && Duelist.Call<bool>("inEvent", player)) return true;
            if (ArenaTournament != null && ArenaTournament.Call<bool>("IsOnTournament", playerId)) return true;
            return false;
        }
        private bool HasFriends(string playerS, string friendS) {
            if (string.IsNullOrEmpty(playerS) || string.IsNullOrEmpty(friendS)) return false;
            ulong playerId, friendId;
            if (ulong.TryParse(playerS, out playerId) && ulong.TryParse(friendS, out friendId)) {
                return HasFriend(playerId, friendId);
            }
            return false;
        }
        private readonly List<string> _hooks = new List<string> {
            nameof(OnTeamCreated), nameof(OnTeamAcceptInvite), nameof(OnTeamKick), nameof(OnTeamLeave), nameof(OnTeamDisbanded), nameof(CanEntityTakeDamage), nameof(OnEntityTakeDamage), nameof(OnEntitySpawned), nameof(OnEntityKill), nameof(OnTurretTarget), nameof(OnSamSiteTarget), nameof(CanChangeCode), nameof(CanUseLockedEntity)
        }
        ;
        private void UpdateCupboardAuth(List<BuildingPrivlidge> buildingPrivlidges, ulong ownerId) {
            if (buildingPrivlidges == null || buildingPrivlidges.Count == 0) return;
            List<PlayerNameID> team = GetTeamMembers(ownerId);
            if (team == null) return;
            foreach (BuildingPrivlidge buildingPrivlidge in buildingPrivlidges) {
                if (buildingPrivlidge.IsDestroyed) continue;
                if (!buildingPrivlidge.authorizedPlayers.Exists(p => p.userid == ownerId)) continue;
                buildingPrivlidge.authorizedPlayers.Clear();
                foreach (PlayerNameID friend in team) {
                    buildingPrivlidge.authorizedPlayers.Add(friend);
                }
                buildingPrivlidge.SendNetworkUpdate();
            }
        }
        private bool AttemptWriteToLogFile(string prefix, string timestamp, string message) {
            try {
                LogToFile(prefix, timestamp + message, this);
            }
            catch (Exception ex) {
                PrintError(ex.ToString());
                return false;
            }
            return true;
        }
        private void OnTeamDisbanded(RelationshipManager.PlayerTeam playerTeam) {
            if (playerTeam == null) return;
            LogMessage(GetLang("TEAM_LOG_6", null, playerTeam.teamID, playerTeam.teamLeader));
            UpdateTeamAuth(playerTeam.members);
        }
        private bool IsFriend(ulong playerId, ulong friendId) {
            return HasFriend(playerId, friendId);
        }
        private static class ObjectCache {
            private static readonly object True = true;
            private static readonly object False = false;
            private static class StaticObjectCache<T> {
                private static readonly Dictionary<T, object> CacheByValue = new Dictionary<T, object>();
                public static object Get(T value) {
                    object cachedObject;
                    if (!CacheByValue.TryGetValue(value, out cachedObject)) {
                        cachedObject = value;
                        CacheByValue[value] = cachedObject;
                    }
                    return cachedObject;
                }
            }
            public static object Get<T>(T value) {
                return StaticObjectCache<T>.Get(value);
            }
            public static object Get(bool value) {
                return value ? True : False;
            }
        }
        private static Queue<LogEntry> _logQueue = new Queue<LogEntry>();
        private void UpdateTeamAuth(List<ulong> teamMembers) {
            if (teamMembers == null || teamMembers.Count == 0) return;
            bool codeLock = _config.CodeLockAuthUse;
            bool cupboard = _config.CupboardAuthUse;
            if(!codeLock && !cupboard) return;
            foreach (ulong member in teamMembers) {
                if (cupboard) {
                    List<BuildingPrivlidge> cupboards;
                    if (_playerCupboardsCache.TryGetValue(member, out cupboards) && cupboards != null && cupboards.Count > 0) {
                        UpdateCupboardAuth(cupboards, member);
                    }
                }
                if (codeLock) {
                    List<CodeLock> memberLocks;
                    if (_playerLocksCache.TryGetValue(member, out memberLocks) && memberLocks != null && memberLocks.Count > 0) {
                        UpdateLockAuth(memberLocks, member);
                    }
                }
            }
        }
        private ulong[] GetFriends(ulong playerId) {
            HashSet<ulong> members = new HashSet<ulong>();
            foreach (string member in GetFriendList(playerId)) {
                ulong parsedMember;
                if (ulong.TryParse(member, out parsedMember)) {
                    members.Add(parsedMember);
                }
            }
            ulong[] memberArray = new ulong[members.Count];
            members.CopyTo(memberArray);
            return memberArray;
        }
        private ulong[] IsFriendOf(ulong playerId) {
            HashSet<ulong> members = new HashSet<ulong>();
            foreach (string member in GetFriendList(playerId)) {
                ulong parsedMember;
                if (ulong.TryParse(member, out parsedMember) && parsedMember != playerId) {
                    members.Add(parsedMember);
                }
            }
            ulong[] memberArray = new ulong[members.Count];
            members.CopyTo(memberArray);
            return memberArray;
        }
        private bool WasFriendS(string playerS, string friendS) => HasFriend(ulong.Parse(playerS), ulong.Parse(friendS));
        private string[] GetFriends(string playerS) {
            ulong playerId;
            if (ulong.TryParse(playerS, out playerId)) {
                ulong[] friendIds = GetFriends(playerId);
                string[] friendStrings = new string[friendIds.Length];
                for (int i = 0; i < friendIds.Length; i++) {
                    friendStrings[i] = friendIds[i].ToString();
                }
                return friendStrings;
            }
            return new string[] {
            }
            ;
        }
        private void OnServerInitialized() {
            StringBuilderInstance = new StringBuilder();
            RelationshipManager.maxTeamSize = _config.MaxTeamSize;
            foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerConnected(player);
            Subscribes();
            foreach (string command in _config.ChatCommands) cmd.AddChatCommand(command, this, nameof(CmdTeamCommand));
            timer.Once(3F, TriggerDelayedInitialization);
        }
        void CmdTeamCommand(BasePlayer player, string command, string[] arg) {
            if (arg?.Length == 0) {
                SendChat(player, GetLang("TEAM_INFO", player.UserIDString));
                return;
            }
            RelationshipManager.PlayerTeam team = RelationshipManager.ServerInstance.FindTeam(player.currentTeam);
            if (team == null) {
                SendChat(player, GetLang("TEAM_NULL", player.UserIDString));
                return;
            }
            switch (arg[0]) {
                case "invite" : case "add" : {
                    if (arg.Length != 2) {
                        SendChat(player, GetLang("TEAM_NULLNICKNAME", player.UserIDString));
                        return;
                    }
                    BasePlayer target = FindOnlinePlayer(player, arg[1]);
                    if (target == null) {
                        return;
                    }
                    if (target == player) {
                        SendChat(player, GetLang("TEAM_NULLNICKNAMENULL", player.UserIDString));
                        return;
                    }
                    if (target.currentTeam != 0) {
                        SendChat(player, GetLang("TEAM_ISCOMMAND", player.UserIDString, target.displayName));
                        return;
                    }
                    if (team.members.Count >= _config.MaxTeamSize) {
                        SendChat(player, GetLang("TEAM_MAXTEAMSIZE", player.UserIDString));
                        return;
                    }
                    timer.Once(_config.InviteAcceptTime, () => {
                        if (!team.members.Contains(target.userID)) {
                            if (team == null) {
                                player.ClearPendingInvite();
                            }
                            else {
                                team.RejectInvite(target);
                            }
                            SendChat(player, GetLang("TEAM_TIMENULL", player.UserIDString));
                            SendChat(target, GetLang("TEAM_TIMENULS", target.UserIDString, player.displayName));
                        }
                    }
                    );
                    team.SendInvite(target);
                    team.MarkDirty();
                    SendChat(player, GetLang("TEAM_IVITE", player.UserIDString, target.displayName));
                    SendChat(target, GetLang("TEAM_INVITETARGET", target.UserIDString, player.displayName));
                    break;
                }
                case "ff" : {
                    if (!_ffTeam.ContainsKey(player.userID)) _ffTeam[player.userID] = false;
                    if (!_ffTeam[player.userID]) {
                        _ffTeam[player.userID] = true;
                        SendChat(player, GetLang("TEAM_FFON", player.UserIDString));
                    }
                    else {
                        _ffTeam[player.userID] = false;
                        SendChat(player, GetLang("TEAM_FFOFF", player.UserIDString));
                    }
                    break;
                }
            }
        }
        private bool IsFriends(string playerS, string friendS) {
            if (string.IsNullOrEmpty(playerS) || string.IsNullOrEmpty(friendS)) return false;
            ulong playerId, friendId;
            if (ulong.TryParse(playerS, out playerId) && ulong.TryParse(friendS, out friendId)) {
                return IsFriend(playerId, friendId);
            }
            return false;
        }
        private string[] GetFriendList(ulong playerId) {
            RelationshipManager.PlayerTeam teamFind = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
            if (teamFind != null) {
                List<ulong> teamMembers = teamFind.members;
                string[] memberStrings = new string[teamMembers.Count];
                for (int i = 0; i < teamMembers.Count; i++) {
                    memberStrings[i] = teamMembers[i].ToString();
                }
                return memberStrings;
            }
            return new string[] {
            }
            ;
        }
        private void OnEntitySpawned(BuildingPrivlidge buildingPrivlidge) => AddCupboardCache(buildingPrivlidge, true);
        private void Unload() {
            SaveData();
            StringBuilderInstance = null;
        }
        private void RemoveCodeLockCache(CodeLock codeLock) {
            if (codeLock == null || !codeLock.OwnerID.IsSteamId()) return;
            List<CodeLock> codeLocks;
            if (_playerLocksCache.TryGetValue(codeLock.OwnerID, out codeLocks) && codeLocks.Contains(codeLock)) codeLocks.Remove(codeLock);
        }
        private void OnTeamKick(RelationshipManager.PlayerTeam team, BasePlayer player, ulong target) {
            NextTick(() => {
                if (team == null) return;
                if (!team.members.Contains(target)) {
                    UpdateTeamAuth(new List<ulong>(team.members) {
                        target
                    }
                    );
                    LogMessage(GetLang("TEAM_LOG_3", null, player.userID, team.teamID, target, ListToStringWithIndex(team.members)));
                }
            }
            );
            SendChat(player, lang.GetMessage("TEAM_CUPBOARCLEAR", this));
        }
        protected override void SaveConfig() {
            Config.WriteObject(_config);
        }
        private void Subscribes() {
            foreach (string hook in _hooks) {
                if (hook == nameof(OnSamSiteTarget) && !_config.SamSiteAuthUse) {
                    continue;
                }
                if (hook == nameof(OnTurretTarget) && !_config.TurretAuthUse) {
                    continue;
                }
                if (hook == nameof(CanUseLockedEntity) && !_config.KeyLockAuthUse) {
                    continue;
                }
                if (hook == nameof(OnTeamCreated) && !_config.LoggerUse) {
                    continue;
                }
                if (hook == nameof(CanChangeCode) && !_config.CodeLockAuthUse) {
                    continue;
                }
                if ((hook == nameof(OnTeamAcceptInvite) || hook == nameof(OnTeamKick) || hook == nameof(OnTeamLeave) || hook == nameof(OnTeamDisbanded) || hook == nameof(OnEntitySpawned) || hook == nameof(OnEntityKill)) && ((!_config.CupboardAuthUse && !_config.CodeLockAuthUse && !_config.LoggerUse))) {
                    continue;
                }
                Subscribe(hook);
            }
        }
        private object CanEntityTakeDamage(BaseEntity entity, HitInfo info) {
            if (entity == null || info == null) return null;
            BasePlayer target = entity as BasePlayer;
            BasePlayer attacker = info.InitiatorPlayer;
            if (attacker == null || target == null || attacker == target) return null;
            if (!HasFriend(attacker.userID, target.userID)) return null;
            if (IsDuel(attacker.userID)) return null;
            if (_ffTeam[attacker.userID]) return null;
            if (_friendFire.Contains(attacker.userID)) return ObjectCache.Get(false);
            _friendFire.Add(attacker.userID);
            timer.Once(5f, () => {
                if (_friendFire.Contains(attacker.userID)) _friendFire.Remove(attacker.userID);
            }
            );
            SendChat(attacker, string.Format(lang.GetMessage("TEAM_FFATTACK", this), target.displayName));
            return ObjectCache.Get(false);
        }
        private void AddCodeLockCache(CodeLock codeLock, bool nowSpawned = false) {
            if (codeLock == null || !codeLock.OwnerID.IsSteamId()) return;
            List<CodeLock> codeLocks;
            if (!_playerLocksCache.TryGetValue(codeLock.OwnerID, out codeLocks)) {
                codeLocks = new List<CodeLock>();
                _playerLocksCache.Add(codeLock.OwnerID, codeLocks);
            }
            if (!codeLocks.Contains(codeLock)) codeLocks.Add(codeLock);
            if (nowSpawned) UpdateLockAuth(new List<CodeLock> {
                codeLock
            }
            , codeLock.OwnerID);
        }
        private void CanChangeCode(BasePlayer player, CodeLock codeLock, string code, bool isGuest) {
            NextTick(() => {
                ulong ownerId = codeLock.OwnerID;
                if (!ownerId.IsSteamId()) return;
                List<PlayerNameID> teamMembers = GetTeamMembers(ownerId);
                ReAuthTeamInCodeLock(teamMembers, codeLock, ownerId);
            }
            );
        }
        private void TriggerDelayedInitialization() {
            foreach (BaseNetworkable serverEntity in BaseNetworkable.serverEntities) {
                if (_config.CupboardAuthUse) {
                    BuildingPrivlidge buildingPrivlidge = serverEntity as BuildingPrivlidge;
                    if (buildingPrivlidge != null) {
                        AddCupboardCache(buildingPrivlidge);
                        continue;
                    }
                }
                if (_config.CodeLockAuthUse) {
                    CodeLock codeLock = serverEntity as CodeLock;
                    if (codeLock != null) {
                        AddCodeLockCache(codeLock);
                    }
                }
            }
        }
        private List<ulong> _friendFire = new List<ulong>();
        private void SendChat(BasePlayer player, string message, string hexColorMsg = "#ffffff", string colortwo = "#fff5070", string customAvatar = "", Chat.ChatChannel channel = Chat.ChatChannel.Global) {
            if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, message, _config.ChatPrefix, customAvatar, hexColorMsg);
            else player.SendConsoleCommand("chat.add", channel, 0, message);
        }
        private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam team, BasePlayer player) {
            NextTick(() => {
                if (team == null || player == null) return;
                if (team.members.Contains(player.userID)) {
                    UpdateTeamAuth(team.members);
                    LogMessage(GetLang("TEAM_LOG_2", null, player.userID, team.teamID, team.teamLeader, ListToStringWithIndex(team.members)));
                }
            }
            );
        }
        private void Init() {
            Unsubscribes();
            LoadData();
        }
        protected override void LoadDefaultConfig() {
            _config = new Configuration();
        }
        private void ValidateConfig() {
            if (_config.MethodCodeLockAuthUse != "guestPlayers" && _config.MethodCodeLockAuthUse != "whitelistPlayers") {
                _config.MethodCodeLockAuthUse = "guestPlayers";
            }
        }
        private void AddCupboardCache(BuildingPrivlidge buildingPrivlidge, bool nowSpawned = false) {
            if (buildingPrivlidge == null || !buildingPrivlidge.OwnerID.IsSteamId()) return;
            List<BuildingPrivlidge> buildingPrivlidges;
            if (!_playerCupboardsCache.TryGetValue(buildingPrivlidge.OwnerID, out buildingPrivlidges)) {
                buildingPrivlidges = new List<BuildingPrivlidge>();
                _playerCupboardsCache.Add(buildingPrivlidge.OwnerID, buildingPrivlidges);
            }
            if (!buildingPrivlidges.Contains(buildingPrivlidge)) buildingPrivlidges.Add(buildingPrivlidge);
            if (nowSpawned) NextTick(() => {
                UpdateCupboardAuth(new List<BuildingPrivlidge> {
                    buildingPrivlidge
                }
                , buildingPrivlidge.OwnerID);
            }
            );
        }
        private string ListToStringWithIndex(List<ulong> list) {
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < list.Count; i++) {
                sb.AppendLine($"\t{i+1}.{list[i]}");
            }
            return sb.ToString();
        }
        private BasePlayer FindOnlinePlayer(BasePlayer player, string nameOrID) {
            if (nameOrID.IsSteamId()) {
                BasePlayer target = BasePlayer.FindByID(ulong.Parse(nameOrID));
                if (target != null) return target;
                SendChat(player, GetLang("TEAM_FOUND", player.UserIDString));
                return null;
            }
            List<BasePlayer> matches = new List<BasePlayer>();
            foreach (BasePlayer p in BasePlayer.activePlayerList) {
                if (p.displayName == nameOrID || string.Equals(p.displayName, nameOrID, StringComparison.CurrentCultureIgnoreCase) || p.displayName.Contains(nameOrID) || p.displayName.ToLower().Contains(nameOrID.ToLower())) {
                    matches.Add(p);
                }
            }
            if (matches.Count == 0) {
                SendChat(player, GetLang("TEAM_FOUND", player.UserIDString));
                return null;
            }
            if (matches.Count == 1) return matches[0];
            string playersMore = "";
            foreach (BasePlayer plr in matches) playersMore = playersMore + "\n" + plr.displayName + " - " + plr.UserIDString;
            SendChat(player, GetLang("TEAM_FOUND_MULTIPLE", player.UserIDString, playersMore));
            return null;
        }
        private readonly Dictionary<ulong, List<CodeLock>> _playerLocksCache = new Dictionary<ulong, List<CodeLock>>();
        private void OnPlayerConnected(BasePlayer player) {
            if (!_ffTeam.ContainsKey(player.userID)) _ffTeam.Add(player.userID, false);
        }
        private object OnTurretTarget(AutoTurret turret, BasePlayer player) {
            if (ReferenceEquals(player, null) || turret.OwnerID <= 0) return null;
            if (HasFriend(turret.OwnerID, player.userID)) return false;
            return null;
        }
        private void OnEntityKill(BuildingPrivlidge buildingPrivlidge) => RemoveCupboardCache(buildingPrivlidge);
        private void OnTeamLeave(RelationshipManager.PlayerTeam team, BasePlayer player) {
            ulong teamLead = team?.teamLeader ?? 0;
            NextTick(() => {
                if (team == null || player == null) return;
                if (!team.members.Contains(player.userID)) {
                    UpdateTeamAuth(new List<ulong>(team.members) {
                        player.userID
                    }
                    );
                }
                string msg = "";
                if (player.userID == teamLead && team.members.Count > 0) {
                    msg = GetLang("TEAM_LOG_4", null, team.teamID, team.teamLeader, ListToStringWithIndex(team.members));
                }
                else if(team.members.Count > 0) {
                    msg = GetLang("TEAM_LOG_5", null, player.userID, team.teamID, team.teamLeader, ListToStringWithIndex(team.members));
                }
                if(!string.IsNullOrEmpty(msg)) LogMessage(msg);
            }
            );
            if(player.userID != team.teamLeader) SendChat(player, lang.GetMessage("TEAM_CUPBOARADDLEAVE", this));
        }
        private string GetCurrentTimestamp() => "[" + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss") + "] ";
    }
}

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