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

FREE Clans : 0.2.10 0.2.10

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Oxide.Plugins {
    using ClansEx;
    [Info("Clans", "k1lly0u", "0.2.10")]
    public class Clans : CovalencePlugin {
#region Fields
        private bool isInitialized = false;
        private Regex hexFilter = new Regex("^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
        public static Clans Instance {
            get;
            private set;
        }
        private static readonly DateTime Epoch = new DateTime(1970, 1, 1);
        private static readonly double MaxUnixSeconds = (DateTime.MaxValue - Epoch).TotalSeconds;
        private const string COLORED_LABEL = "[{0}]{1}[/#]";
#endregion
#region Oxide Hooks
        private void Loaded() {
            Instance = this;
            LoadData();
        }
        protected override void LoadDefaultMessages() => lang.RegisterMessages(Messages, this);
        private void OnServerInitialized() {
            if (!configData.Tags.Enabled) Unsubscribe(nameof(OnPluginLoaded));
            InitializeClans();
        }
        private void OnPluginLoaded(Plugin plugin) {
            if (configData.Tags.Enabled && plugin?.Title == "Better Chat") Interface.CallHook("API_RegisterThirdPartyTitle", this, new Func<IPlayer, string>(BetterChat_FormattedClanTag));
        }
        private void OnUserConnected(IPlayer player) {
            Clan clan = storedData?.FindClanByID(player.Id);
            if (clan != null) {
                clan.OnPlayerConnected(player);
            }
            else {
                List<string> invites;
                if (storedData.playerInvites.TryGetValue(player.Id, out invites)) {
                    player.Reply(string.Format(Message("Notification.PendingInvites", player.Id), invites.ToSentence(), "clan"));
                }
            }
        }
        private void OnUserDisconnected(IPlayer player) => storedData?.FindClanByID(player.Id)?.OnPlayerDisconnected(player);
        private void Unload() {
            SaveData();
            Instance = null;
        }
#endregion
#region Functions
        private void InitializeClans() {
            Puts("Initializing Clans...");
            List<string> purgedClans = ListPool.Get<string>();
            foreach (KeyValuePair<string, Clan> kvp in storedData.clans) {
                Clan clan = kvp.Value;
                if (clan.ClanMembers.Count == 0 || (configData.Purge.Enabled && UnixTimeStampUTC() - clan.LastOnlineTime > (configData.Purge.OlderThanDays * 86400))) {
                    purgedClans.Add(kvp.Key);
                    continue;
                }
                if (configData.Clans.Alliance.Enabled) {
                    for (int i = clan.AllianceInvites.Count - 1; i >= 0; i--) {
                        KeyValuePair<string, double> allianceInvite = clan.AllianceInvites.ElementAt(i);
                        if (!storedData.clans.ContainsKey(allianceInvite.Key) || (UnixTimeStampUTC() - allianceInvite.Value > configData.Clans.Invites.AllianceInviteExpireTime)) clan.AllianceInvites.Remove(allianceInvite.Key);
                    }
                    for (int i = clan.Alliances.Count - 1; i >= 0; i--) {
                        string allyTag = clan.Alliances.ElementAt(i);
                        if (!storedData.clans.ContainsKey(allyTag)) clan.Alliances.Remove(allyTag);
                    }
                }
                for (int i = clan.MemberInvites.Count - 1; i >= 0; i--) {
                    KeyValuePair<string, Clan.MemberInvite> memberInvite = clan.MemberInvites.ElementAt(i);
                    if (UnixTimeStampUTC() - memberInvite.Value.ExpiryTime > configData.Clans.Invites.MemberInviteExpireTime) clan.MemberInvites.Remove(memberInvite.Key);
                }
                foreach (KeyValuePair<string, Clan.Member> member in clan.ClanMembers) storedData.RegisterPlayer(member.Key, clan.Tag);
            }
            if (purgedClans.Count > 0) {
                Puts($"Purging {purgedClans.Count} expired or invalid clans");
                StringBuilder str = new StringBuilder();
                for (int i = 0; i < purgedClans.Count; i++) {
                    string tag = purgedClans[i];
                    Clan clan = storedData.clans[tag];
                    if (clan == null) continue;
                    str.Append($"{(i > 0 ? "\n" : "")}Purged - [{tag}] | {clan.Description} | Owner: {clan.OwnerID} | Last Online: {UnixTimeStampToDateTime(clan.LastOnlineTime)}");
                    storedData.clans.Remove(tag);
                }
                if (configData.Purge.ListPurgedClans) {
                    Puts(str.ToString());
                    if (configData.Options.LogChanges) LogToFile(Title, str.ToString(), this);
                }
            }
            Puts($"Loaded {storedData.clans.Count} clans!");
            ListPool.Free(ref purgedClans);
            if (configData.Tags.Enabled) Interface.CallHook("API_RegisterThirdPartyTitle", this, new Func<Oxide.Core.Libraries.Covalence.IPlayer, string>(BetterChat_FormattedClanTag));
            isInitialized = true;
            foreach (IPlayer player in players.Connected) OnUserConnected(player);
            TimedSaveData();
        }
        private bool ClanTagExists(string tag) {
            ICollection<string> collection = storedData.clans.Keys;
            for (int i = 0; i < collection.Count; i++) {
                if (collection.ElementAt(i).Equals(tag, StringComparison.OrdinalIgnoreCase)) return true;
            }
            return false;
        }
        private string FormatTime(double time) {
            TimeSpan dateDifference = TimeSpan.FromSeconds((float)time);
            int days = dateDifference.Days;
            int hours = dateDifference.Hours + (days * 24);
            int mins = dateDifference.Minutes;
            int secs = dateDifference.Seconds;
            if (hours > 0) return string.Format("{0:00}h:{1:00}m:{2:00}s", hours, mins, secs);
            else if (mins > 0) return string.Format("{0:00}m:{1:00}s", mins, secs);
            else return string.Format("{0:00}s", secs);
        }
        private string BetterChat_FormattedClanTag(IPlayer player) {
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) return string.Empty;
            return $"[#{(string.IsNullOrEmpty(clan.TagColor) || !configData.Tags.CustomColors ? configData.Tags.TagColor.Replace("#", "") : clan.TagColor.Replace("#", ""))}][+{configData.Tags.TagSize}]{configData.Tags.TagOpen}{clan.Tag}{configData.Tags.TagClose}[/+][/#]";
        }
        private static int UnixTimeStampUTC() => (int)DateTime.UtcNow.Subtract(Epoch).TotalSeconds;
        private static DateTime UnixTimeStampToDateTime(double unixTimeStamp) {
            return unixTimeStamp > MaxUnixSeconds ? Epoch.AddMilliseconds(unixTimeStamp) : Epoch.AddSeconds(unixTimeStamp);
        }
#endregion
#region Clan Management
        [HookMethod("CreateClan")]
        public void CreateClan(IPlayer player, string tag, string description) {
            if (player == null) return;
            if (storedData.FindClanByID(player.Id) != null) {
                player.Reply(Message("Notification.Create.InExistingClan", player.Id));
                return;
            }
            if (tag.Length < configData.Tags.TagLength.Minimum || tag.Length > configData.Tags.TagLength.Maximum) {
                player.Reply(string.Format(Message("Notification.Create.InvalidTagLength", player.Id), configData.Tags.TagLength.Minimum, configData.Tags.TagLength.Maximum));
                return;
            }
            if (ClanTagExists(tag)) {
                player.Reply(Message("Notification.Create.ClanExists", player.Id));
                return;
            }
            storedData.clans[tag] = new Clan(player, tag, description);
            storedData.RegisterPlayer(player.Id, tag);
            player.Reply(string.Format(Message("Notification.Create.Success", player.Id), tag));
            Interface.CallHook("OnClanCreate", tag);
            if (configData.Options.LogChanges) LogToFile(Title, $"{player.Name} created the clan [{tag}]", this);
        }
        [HookMethod("InvitePlayer")]
        public bool InvitePlayer(IPlayer inviter, string targetId) {
            IPlayer invitee = covalence.Players.FindPlayerById(targetId) ?? null;
            if (invitee == null) {
                inviter.Reply(string.Format(Message("Notification.Generic.UnableToFindPlayer", inviter.Id), targetId));
                return false;
            }
            return InvitePlayer(inviter, invitee);
        }
        [HookMethod("InvitePlayer")]
        public bool InvitePlayer(IPlayer inviter, IPlayer invitee) {
            if (inviter == null || invitee == null) return false;
            Clan clan = storedData.FindClanByID(inviter.Id);
            if (clan == null) {
                inviter.Reply(Message("Notification.Generic.NoClan", inviter.Id));
                return false;
            }
            Clan other = storedData.FindClanByID(invitee.Id);
            if (other != null) {
                inviter.Reply(string.Format(Message("Notification.Invite.InClan", inviter.Id), invitee.Name));
                return false;
            }
            return clan.InvitePlayer(inviter, invitee);
        }
        [HookMethod("WithdrawInvite")]
        public bool WithdrawInvite(IPlayer player, string partialNameOrID) {
            if (player == null) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            if (!clan.IsOwner(player.Id) && !clan.IsModerator(player.Id)) {
                player.Reply(Message("Notification.WithdrawInvite.NoPermissions", player.Id));
                return false;
            }
            foreach (KeyValuePair<string, Clan.MemberInvite> invite in clan.MemberInvites) {
                if (partialNameOrID.Equals(invite.Key) || invite.Value.DisplayName.Contains(partialNameOrID)) {
                    storedData.RevokePlayerInvite(partialNameOrID, clan.Tag);
                    clan.MemberInvites.Remove(invite.Key);
                    clan.Broadcast("Notification.WithdrawInvite.Success", player.Name, invite.Value.DisplayName);
                    return true;
                }
            }
            player.Reply(string.Format(Message("Notification.WithdrawInvite.UnableToFind", player.Id), partialNameOrID));
            return false;
        }
        [HookMethod("RejectInvite")]
        public bool RejectInvite(IPlayer player, string tag) {
            if (player == null) return false;
            Clan clan = storedData.FindClan(tag);
            if (clan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), tag));
                return false;
            }
            if (!clan.MemberInvites.ContainsKey(player.Id)) {
                player.Reply(string.Format(Message("Notification.RejectInvite.InvalidInvite", player.Id), tag));
                return false;
            }
            clan.MemberInvites.Remove(player.Id);
            storedData.OnInviteRejected(player.Id, clan.Tag);
            clan.Broadcast("Notification.RejectInvite.Reply", player.Name);
            player.Reply(string.Format(Message("Notification.RejectInvite.PlayerMessage", player.Id), tag));
            if (configData.Options.LogChanges) Instance.LogToFile(Instance.Title, $"{player.Name} rejected their invite to [{tag}]", Instance);
            return true;
        }
        [HookMethod("JoinClan")]
        public bool JoinClan(IPlayer player, string tag) {
            if (player == null || string.IsNullOrEmpty(tag)) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan != null) {
                player.Reply(Message("Notification.Join.InExistingClan", player.Id));
                return false;
            }
            clan = storedData.FindClan(tag);
            if (clan == null) return false;
            return clan.JoinClan(player);
        }
        [HookMethod("LeaveClan")]
        public bool LeaveClan(IPlayer player) {
            if (player == null) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            return clan.LeaveClan(player);
        }
        [HookMethod("KickPlayer")]
        public bool KickPlayer(IPlayer player, string playerId) {
            if (player == null) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            return clan.KickMember(player, playerId);
        }
        [HookMethod("PromotePlayer")]
        public bool PromotePlayer(IPlayer promoter, string targetId) {
            if (promoter == null) return false;
            Clan clan = storedData.FindClanByID(promoter.Id);
            if (clan == null) {
                promoter.Reply(Message("Notification.Generic.NoClan", promoter.Id));
                return false;
            }
            Clan other = storedData.FindClanByID(targetId);
            if (other == null || !clan.Tag.Equals(other.Tag)) {
                string Name = covalence.Players.FindPlayer(targetId)?.Name ?? targetId;
                promoter.Reply(string.Format(Message("Notification.Promotion.TargetNoClan", promoter.Id), Name));
                return false;
            }
            return clan.PromotePlayer(promoter, targetId);
        }
        [HookMethod("DemotePlayer")]
        public bool DemotePlayer(IPlayer demoter, string targetId) {
            if (demoter == null) return false;
            Clan clan = storedData.FindClanByID(demoter.Id);
            if (clan == null) {
                demoter.Reply(Message("Notification.Generic.NoClan", demoter.Id));
                return false;
            }
            Clan other = storedData.FindClanByID(targetId);
            if (other == null || !clan.Tag.Equals(other.Tag)) {
                string Name = covalence.Players.FindPlayer(targetId)?.Name ?? targetId;
                demoter.Reply(string.Format(Message("Notification.Promotion.TargetNoClan", demoter.Id), Name));
                return false;
            }
            return clan.DemotePlayer(demoter, targetId);
        }
        [HookMethod("DisbandClan")]
        public bool DisbandClan(IPlayer player) {
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            if (!clan.IsOwner(player.Id)) {
                player.Reply(Message("Notification.Disband.NotOwner", player.Id));
                return false;
            }
            string tag = clan.Tag;
            clan.Broadcast("Notification.Disband.Reply", Array.Empty<object>());
            clan.DisbandClan();
            player.Reply(string.Format(Message("Notification.Disband.Success", player.Id), tag));
            return true;
        }
#endregion
#region Alliance Management
        [HookMethod("OfferAlliance")]
        public bool OfferAlliance(IPlayer player, string tag) {
            if (!configData.Clans.Alliance.Enabled) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            Clan alliedClan = storedData.FindClan(tag);
            if (alliedClan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), tag));
                return false;
            }
            if (!clan.IsOwner(player.Id)) {
                player.Reply(Message("Notification.Alliance.NoPermissions", player.Id));
                return false;
            }
            if (clan.AllianceInvites.ContainsKey(tag) && (UnixTimeStampUTC() - clan.AllianceInvites[tag] < configData.Clans.Invites.AllianceInviteExpireTime)) {
                player.Reply(string.Format(Message("Notification.Alliance.PendingInvite", player.Id), tag));
                return false;
            }
            if (clan.AllianceInviteCount >= configData.Clans.Invites.AllianceInviteLimit) {
                player.Reply(Message("Notification.Alliance.MaximumInvites", player.Id));
                return false;
            }
            if (clan.AllianceCount >= configData.Clans.Alliance.AllianceLimit) {
                player.Reply(Message("Notification.Alliance.MaximumAlliances", player.Id));
                return false;
            }
            clan.AllianceInvites[tag] = UnixTimeStampUTC();
            alliedClan.IncomingAlliances.Add(clan.Tag);
            player.Reply(string.Format(Message("Notification.Alliance.InviteSent", player.Id), tag, FormatTime(configData.Clans.Invites.AllianceInviteExpireTime)));
            alliedClan.Broadcast("Notification.Alliance.InviteReceived", clan.Tag, FormatTime(configData.Clans.Invites.AllianceInviteExpireTime), "ally");
            return true;
        }
        [HookMethod("WithdrawAlliance")]
        public bool WithdrawAlliance(IPlayer player, string tag) {
            if (!configData.Clans.Alliance.Enabled) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            Clan alliedClan = storedData.FindClan(tag);
            if (alliedClan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), tag));
                return false;
            }
            if (!clan.IsOwner(player.Id)) {
                player.Reply(Message("Notification.Alliance.NoPermissions", player.Id));
                return false;
            }
            if (!clan.AllianceInvites.ContainsKey(tag)) {
                player.Reply(string.Format(Message("Notification.Alliance.NoActiveInvite", player.Id), tag));
                return false;
            }
            clan.AllianceInvites.Remove(tag);
            alliedClan.IncomingAlliances.Remove(clan.Tag);
            clan.Broadcast("Notification.Alliance.WithdrawnClan", player.Name, tag);
            alliedClan.Broadcast("Notification.Alliance.WithdrawnTarget", clan.Tag);
            clan.MarkDirty();
            return true;
        }
        [HookMethod("AcceptAlliance")]
        public bool AcceptAlliance(IPlayer player, string tag) {
            if (!configData.Clans.Alliance.Enabled) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(Message("Notification.Generic.NoClan", player.Id));
                return false;
            }
            Clan alliedClan = storedData.FindClan(tag);
            if (alliedClan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), tag));
                return false;
            }
            if (!clan.IsOwner(player.Id)) {
                player.Reply(Message("Notification.Alliance.NoPermissions", player.Id));
                return false;
            }
            bool noActiveInvite = !alliedClan.AllianceInvites.ContainsKey(clan.Tag);
            if ((UnixTimeStampUTC() - alliedClan.AllianceInvites[clan.Tag] > configData.Clans.Invites.AllianceInviteExpireTime)) {
                alliedClan.AllianceInvites.Remove(clan.Tag);
                noActiveInvite = true;
            }
            if (noActiveInvite) {
                player.Reply(string.Format(Message("Notification.Alliance.NoActiveInviteFrom", player.Id), tag));
                return false;
            }
            if (alliedClan.AllianceCount >= configData.Clans.Alliance.AllianceLimit) {
                player.Reply(string.Format(Message("Notification.Alliance.AtLimitTarget", player.Id), tag));
                return false;
            }
            if (clan.AllianceCount >= configData.Clans.Alliance.AllianceLimit) {
                player.Reply(string.Format(Message("Notification.Alliance.AtLimitSelf", player.Id), tag));
                return false;
            }
            clan.Alliances.Add(tag);
            clan.IncomingAlliances.Remove(tag);
            alliedClan.Alliances.Add(clan.Tag);
            alliedClan.AllianceInvites.Remove(clan.Tag);
            clan.MarkDirty();
            alliedClan.MarkDirty();
            clan.Broadcast("Notification.Alliance.Formed", clan.Tag, alliedClan.Tag);
            alliedClan.Broadcast("Notification.Alliance.Formed", clan.Tag, alliedClan.Tag);
            Interface.Oxide.CallHook("OnClanUpdate", clan.Tag);
            Interface.Oxide.CallHook("OnClanUpdate", alliedClan.Tag);
            Interface.Oxide.CallHook("OnClanAllianceCreated", clan.Tag, alliedClan.Tag);
            return true;
        }
        [HookMethod("RejectAlliance")]
        public bool RejectAlliance(IPlayer player, string tag) {
            if (!configData.Clans.Alliance.Enabled) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), tag));
                return false;
            }
            Clan alliedClan = storedData.FindClan(tag);
            if (alliedClan == null) {
                player.Reply(Message("Notification.Generic.InvalidClan", player.Id));
                return false;
            }
            if (!clan.IsOwner(player.Id)) {
                player.Reply(Message("Notification.Alliance.NoPermissions", player.Id));
                return false;
            }
            if (!alliedClan.AllianceInvites.ContainsKey(clan.Tag) || (UnixTimeStampUTC() - alliedClan.AllianceInvites[clan.Tag] > configData.Clans.Invites.AllianceInviteExpireTime)) {
                player.Reply(string.Format(Message("Notification.Alliance.NoActiveInvite", player.Id), tag));
                return false;
            }
            clan.IncomingAlliances.Remove(tag);
            alliedClan.AllianceInvites.Remove(clan.Tag);
            alliedClan.MarkDirty();
            clan.Broadcast("Notification.Alliance.Rejected", clan.Tag, alliedClan.Tag);
            alliedClan.Broadcast("Notification.Alliance.Rejected", clan.Tag, alliedClan.Tag);
            return true;
        }
        [HookMethod("RevokeAlliance")]
        public bool RevokeAlliance(IPlayer player, string tag) {
            if (!configData.Clans.Alliance.Enabled) return false;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), tag));
                return false;
            }
            Clan alliedClan = storedData.FindClan(tag);
            if (alliedClan == null) {
                player.Reply(Message("Notification.Generic.InvalidClan", player.Id));
                return false;
            }
            if (!clan.IsOwner(player.Id)) {
                player.Reply(Message("Notification.Alliance.NoPermissions", player.Id));
                return false;
            }
            if (!clan.Alliances.Contains(alliedClan.Tag)) {
                player.Reply(string.Format(Message("Notification.Alliance.NoActiveAlliance", player.Id), alliedClan.Tag));
                return false;
            }
            alliedClan.Alliances.Remove(clan.Tag);
            clan.Alliances.Remove(alliedClan.Tag);
            alliedClan.MarkDirty();
            clan.MarkDirty();
            clan.Broadcast("Notification.Alliance.Revoked", clan.Tag, alliedClan.Tag);
            alliedClan.Broadcast("Notification.Alliance.Revoked", clan.Tag, alliedClan.Tag);
            Interface.Oxide.CallHook("OnClanUpdate", clan.Tag);
            Interface.Oxide.CallHook("OnClanUpdate", alliedClan.Tag);
            Interface.Oxide.CallHook("OnClanAllianceDissolved", clan.Tag, alliedClan.Tag);
            return true;
        }
#endregion
#region Chat
        private void ClanChat(IPlayer player, string message) {
            if (player == null) return;
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) return;
            string str = string.Format(Message("Chat.Alliance.Format"), clan.Tag, clan.GetRoleColor(player.Id), player.Name, message);
            clan.Broadcast(string.Format(Message("Chat.Clan.Prefix"), str));
            Interface.CallHook("OnClanChat", player, message, clan.Tag);
        }
        private void AllianceChat(IPlayer player, string message) {
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) return;
            string str = string.Format(Message("Chat.Alliance.Format"), clan.Tag, clan.GetRoleColor(player.Id), player.Name, message);
            clan.Broadcast(string.Format(Message("Chat.Alliance.Prefix"), str));
            for (int i = 0; i < clan.AllianceCount; i++) {
                Clan alliedClan = storedData.FindClan(clan.Alliances.ElementAt(i));
                if (alliedClan != null) {
                    alliedClan.Broadcast(string.Format(Message("Chat.Alliance.Prefix"), str));
                }
            }
            Interface.CallHook("OnAllianceChat", player, message, clan.Tag);
        }
#endregion
#region Chat Commands
        [Command("a")]
        private void cmdAllianceChat(IPlayer player, string command, string[] args) {
            if (!configData.Clans.Alliance.Enabled || args?.Length == 0) return;
            AllianceChat(player, string.Join(" ", args));
        }
        [Command("c")]
        private void cmdClanChat(IPlayer player, string command, string[] args) {
            if (args?.Length == 0) return;
            ClanChat(player, string.Join(" ", args));
        }
        [Command("cinfo")]
        private void cmdChatClanInfo(IPlayer player, string command, string[] args) {
            if (args?.Length == 0) {
                player.Reply(Message("Notification.Generic.SpecifyClanTag", player.Id));
                return;
            }
            Clan clan = storedData.FindClan(args[0]);
            if (clan == null) {
                player.Reply(string.Format(Message("Notification.Generic.InvalidClan", player.Id), args[0]));
                return;
            }
            clan.PrintClanInfo(player);
        }
        [Command("clanhelp")]
        private void cmdChatClanHelp(IPlayer player, string command, string[] args) {
            StringBuilder sb = new StringBuilder();
            Clan clan = storedData.FindClanByID(player.Id);
            if (clan == null) {
                sb.Append(Message("Notification.ClanInfo.Title", player.Id));
                sb.Append(string.Format(Message("Notification.ClanHelp.NoClan", player.Id), "clan"));
                player.Reply(sb.ToString());
                return;
            }
            sb.Append(Message("Notification.ClanInfo.Title", player.Id));
            sb.Append(string.Format(Message("Notification.ClanHelp.Basic", player.Id), "clan", "c"));
            if (clan.IsModerator(player.Id) || clan.OwnerID.Equals(player.Id)) {
                if (configData.Clans.Alliance.Enabled && clan.OwnerID.Equals(player.Id)) sb.Append(string.Format(Message("Notification.ClanHelp.Alliance", player.Id), "ally"));
                sb.Append(string.Format(Message("Notification.ClanHelp.Moderator", player.Id), "clan"));
            }
            if (clan.OwnerID.Equals(player.Id)) {
                sb.Append(string.Format(Message("Notification.ClanHelp.Owner", player.Id), "clan"));
                if (configData.Tags.CustomColors) sb.Append(string.Format(Message("Notification.ClanHelp.TagColor", player.Id), "clan"));
            }
            player.Reply(sb.ToString());
        }
        [Command("ally")]
        private void cmdChatClanAlly(IPlayer player, string command, string[] args) {
            if (!configData.Clans.Alliance.Enabled) return;
            if (args?.Length < 2) {
                player.Reply(string.Format(Message("Notification.ClanHelp.Alliance", player.Id), "ally"));
                return;
            }
            string tag = args[1];
            switch (args[0].ToLower()) {
                case "invite" : OfferAlliance(player, tag);
                return;
                case "withdraw" : WithdrawAlliance(player, tag);
                return;
                case "accept" : AcceptAlliance(player, tag);
                return;
                case "reject" : RejectAlliance(player, tag);
                return;
                case "revoke" : RevokeAlliance(player, tag);
                return;
                default : player.Reply(string.Format(Message("Notification.ClanHelp.Alliance", player.Id), "ally"));
                return;
            }
        }
        [Command("clan")]
        private void cmdChatClan(IPlayer player, string command, string[] args) {
            Clan clan = storedData.FindClanByID(player.Id);
            if (args?.Length == 0) {
                StringBuilder sb = new StringBuilder();
                if (clan == null) {
                    sb.Append(Message("Notification.ClanInfo.Title", player.Id));
                    sb.Append(Message("Notification.Clan.NotInAClan", player.Id));
                    sb.Append(string.Format(Message("Notification.Clan.Help", player.Id), "clanhelp"));
                    player.Reply(sb.ToString());
                    sb.Clear();
                }
                else {
                    sb.Append(Message("Notification.ClanInfo.Title", player.Id));
                    sb.Append(string.Format(Message((clan.IsOwner(player.Id) ? "Notification.Clan.OwnerOf" : clan.IsModerator(player.Id) ? "Notification.Clan.ModeratorOf" : "Notification.Clan.MemberOf"), player.Id), clan.Tag, clan.OnlineCount, clan.MemberCount));
                    sb.Append(string.Format(Message("Notification.Clan.MembersOnline", player.Id), clan.GetMembersOnline()));
                    sb.Append(string.Format(Message("Notification.Clan.Help", player.Id), "clanhelp"));
                    player.Reply(sb.ToString());
                    sb.Clear();
                }
                return;
            }
            string tag = clan?.Tag ?? string.Empty;
            switch (args[0].ToLower()) {
                case "create" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.CreateSyntax", player.Id), "clan"));
                    return;
                }
                CreateClan(player, args[1], args.Length > 2 ? string.Join(" ", args.Skip(2)) : string.Empty);
                return;
                case "leave" : LeaveClan(player);
                return;
                case "invite" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.InviteSyntax", player.Id), "clan"));
                    return;
                }
                IPlayer invitee = players.FindPlayer(args[1]);
                if (invitee == null) {
                    player.Reply(string.Format(Message("Notification.Generic.UnableToFindPlayer", player.Id), args[1]));
                    return;
                }
                if (invitee == player) {
                    player.Reply(Message("Notification.Generic.CommandSelf", player.Id));
                    return;
                }
                InvitePlayer(player, invitee);
                return;
                case "withdraw" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.WithdrawSyntax", player.Id), "clan"));
                    return;
                }
                WithdrawInvite(player, args[1]);
                return;
                case "accept" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.AcceptSyntax", player.Id), "clan"));
                    return;
                }
                JoinClan(player, args[1]);
                return;
                case "reject" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.RejectSyntax", player.Id), "clan"));
                    return;
                }
                RejectInvite(player, args[1]);
                return;
                case "kick" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.KickSyntax", player.Id), "clan"));
                    return;
                }
                string target = clan.FindPlayer(args[1]);
                if (string.IsNullOrEmpty(target)) {
                    player.Reply(Message("Notification.Kick.NoPlayerFound", player.Id));
                    return;
                }
                if (target == player.Id) {
                    player.Reply(Message("Notification.Generic.CommandSelf", player.Id));
                    return;
                }
                KickPlayer(player, target);
                return;
                case "promote" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.PromoteSyntax", player.Id), "clan"));
                    return;
                }
                string promotee = clan.FindPlayer(args[1]);
                if (string.IsNullOrEmpty(promotee)) {
                    player.Reply(string.Format(Message("Notification.Generic.UnableToFindPlayer", player.Id), args[1]));
                    return;
                }
                if (promotee == player.Id) {
                    player.Reply(Message("Notification.Generic.CommandSelf", player.Id));
                    return;
                }
                PromotePlayer(player, promotee);
                return;
                case "demote" : if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.DemoteSyntax", player.Id), "clan"));
                    return;
                }
                string demotee = clan.FindPlayer(args[1]);
                if (string.IsNullOrEmpty(demotee)) {
                    player.Reply(string.Format(Message("Notification.Generic.UnableToFindPlayer", player.Id), args[1]));
                    return;
                }
                if (demotee == player.Id) {
                    player.Reply(Message("Notification.Generic.CommandSelf", player.Id));
                    return;
                }
                DemotePlayer(player, demotee);
                return;
                case "disband" : if (args.Length < 2 || !args[1].Equals("forever", StringComparison.OrdinalIgnoreCase)) {
                    player.Reply(string.Format(Message("Notification.Clan.DisbandSyntax", player.Id), "clan"));
                    return;
                }
                if (clan == null) {
                    player.Reply(Message("Notification.Generic.NoClan", player.Id));
                    return;
                }
                if (!clan.IsOwner(player.Id)) {
                    player.Reply(Message("Notification.Disband.NotOwner", player.Id));
                    return;
                }
                clan.Broadcast("Notification.Disband.Reply", Array.Empty<object>());
                clan.DisbandClan();
                player.Reply(string.Format(Message("Notification.Disband.Success", player.Id), tag));
                return;
                case "tagcolor" : if (!configData.Tags.CustomColors) {
                    player.Reply(Message("Notification.Clan.TagColorDisabled", player.Id));
                    return;
                }
                if (args.Length < 2) {
                    player.Reply(string.Format(Message("Notification.Clan.TagColorSyntax", player.Id), "clan"));
                    return;
                }
                if (!clan.IsOwner(player.Id)) {
                    player.Reply(Message("Notification.Disband.NotOwner", player.Id));
                    return;
                }
                string hexColor = args[1].ToUpper();
                if (hexColor.Equals("RESET")) {
                    clan.TagColor = string.Empty;
                    player.Reply(Message("Notification.Clan.TagColorReset", player.Id));
                    return;
                }
                if (hexColor.Length < 6 || hexColor.Length > 6 || !hexFilter.IsMatch(hexColor)) {
                    player.Reply(Message("Notification.Clan.TagColorFormat", player.Id));
                    return;
                }
                clan.TagColor = hexColor;
                player.Reply(string.Format(Message("Notification.Clan.TagColorSet", player.Id), clan.TagColor));
                return;
                default : player.Reply(string.Format(Message("Notification.Clan.Help", player.Id), "clanhelp"));
                return;
            }
        }
#endregion
#region Hook Rewrite
        private static readonly DateTime OnClanHookDeprecation = new DateTime(2027, 6, 1);
#if RUST
        private static readonly List<ulong> RustMemberList = new List<ulong>();
#endif
        private static readonly List<string> UniversalMemberList = new List<string>();
        private static void OnClanMemberJoined(string tag, string joining, ICollection<string> members) {
            const string HOOK_NAME = "OnClanMemberJoined";
            const string NEW_HOOK = "OnClanMemberJoined(string tag, string joining, List<string> members)";
#if RUST
            RustMemberList.Clear();
#endif
            UniversalMemberList.Clear();
            foreach (string member in members) {
#if RUST
                RustMemberList.Add(ulong.Parse(member));
#endif
                UniversalMemberList.Add(member);
            }
#if RUST
            Interface.CallHook(HOOK_NAME, tag, ulong.Parse(joining), RustMemberList);
#endif
            Interface.CallHook(HOOK_NAME, tag, joining, UniversalMemberList);
            // Deprecated
            Interface.Oxide.CallDeprecatedHook(HOOK_NAME, NEW_HOOK, OnClanHookDeprecation, joining, tag);
            Interface.Oxide.CallDeprecatedHook(HOOK_NAME, NEW_HOOK, OnClanHookDeprecation, joining, UniversalMemberList);
#if RUST
            RustMemberList.Clear();
#endif
            UniversalMemberList.Clear();
        }
        private static void OnClanMemberGone(string tag, string leaving, ICollection<string> members) {
            const string HOOK_NAME = "OnClanMemberGone";
            const string NEW_HOOK = "OnClanMemberGone(string tag, string leaving, List<string> members)";
#if RUST
            RustMemberList.Clear();
#endif
            UniversalMemberList.Clear();
            foreach (string member in members) {
#if RUST
                RustMemberList.Add(ulong.Parse(member));
#endif
                UniversalMemberList.Add(member);
            }
#if RUST
            Interface.CallHook(HOOK_NAME, tag, ulong.Parse(leaving), RustMemberList);
#endif
            Interface.CallHook(HOOK_NAME, tag, leaving, UniversalMemberList);
            // Deprecated
            Interface.Oxide.CallDeprecatedHook(HOOK_NAME, NEW_HOOK, OnClanHookDeprecation, leaving, tag);
            Interface.Oxide.CallDeprecatedHook(HOOK_NAME, NEW_HOOK, OnClanHookDeprecation, leaving, UniversalMemberList);
#if RUST
            RustMemberList.Clear();
#endif
            UniversalMemberList.Clear();
        }
        private static void OnClanDisbanded(string tag, ICollection<string> members) {
            const string HOOK_NAME = "OnClanDisbanded";
            const string NEW_HOOK = "OnClanDisbanded(string tag, List<string> members)";
#if RUST
            RustMemberList.Clear();
#endif
            UniversalMemberList.Clear();
            foreach (string member in members) {
#if RUST
                RustMemberList.Add(ulong.Parse(member));
#endif
                UniversalMemberList.Add(member);
            }
#if RUST
            Interface.CallHook(HOOK_NAME, tag, RustMemberList);
#endif
            Interface.CallHook(HOOK_NAME, tag, UniversalMemberList);
            // Deprecated
            Interface.CallDeprecatedHook(HOOK_NAME, NEW_HOOK, OnClanHookDeprecation, UniversalMemberList);
            Interface.CallDeprecatedHook(HOOK_NAME, NEW_HOOK, OnClanHookDeprecation, tag);
#if RUST
            RustMemberList.Clear();
#endif
            UniversalMemberList.Clear();
        }
#endregion
#region API
        private JObject GetClan(string tag) {
            if (!string.IsNullOrEmpty(tag)) return storedData.FindClan(tag)?.ToJObject();
            return null;
        }
        private JArray GetAllClans() => new JArray(storedData.clans.Keys);
        private string GetClanOf(string playerId) => storedData.FindClanByID(playerId)?.Tag ?? null;
        private string GetClanOf(ulong playerId) => GetClanOf(playerId.ToString());
        private string GetClanOf(IPlayer player) => GetClanOf(player?.Id ?? string.Empty);
#if RUST
        private string GetClanOf(BasePlayer player) => GetClanOf(player?.UserIDString ?? string.Empty);
#endif
#if HURTWORLD
        private string GetClanOf(PlayerSession session) => GetClanOf(session?.SteamId ?? string.Empty);
#endif
        private List<string> GetClanMembers(ulong playerId) => GetClanMembers(playerId.ToString());
        private List<string> GetClanMembers(string playerId) => storedData.FindClanByID(playerId)?.ClanMembers.Keys.ToList() ?? new List<string>();
        private object HasFriend(ulong ownerId, ulong playerId) => HasFriend(ownerId.ToString(), playerId.ToString());
        private object HasFriend(string ownerId, string playerId) {
            Clan clanOwner = storedData.FindClanByID(ownerId);
            if (clanOwner == null) return null;
            Clan clanFriend = storedData.FindClanByID(playerId);
            if (clanFriend == null) return null;
            return clanOwner.Tag.Equals(clanFriend.Tag);
        }
        private bool IsClanMember(ulong playerId, ulong otherId) => IsClanMember(playerId.ToString(), otherId.ToString());
        private bool IsClanMember(string playerId, string otherId) {
            Clan clanPlayer = storedData.FindClanByID(playerId);
            if (clanPlayer == null) return false;
            Clan clanOther = storedData.FindClanByID(otherId);
            if (clanOther == null) return false;
            return clanPlayer.Tag.Equals(clanOther.Tag);
        }
        private bool IsMemberOrAlly(ulong playerId, ulong otherId) => IsMemberOrAlly(playerId.ToString(), otherId.ToString());
        private bool IsMemberOrAlly(string playerId, string otherId) {
            Clan playerClan = storedData.FindClanByID(playerId);
            if (playerClan == null) return false;
            Clan otherClan = storedData.FindClanByID(otherId);
            if (otherClan == null) return false;
            if ((playerClan.Tag.Equals(otherClan.Tag)) || playerClan.Alliances.Contains(otherClan.Tag)) return true;
            return false;
        }
        private bool IsAllyPlayer(ulong playerId, ulong otherId) => IsAllyPlayer(playerId.ToString(), otherId.ToString());
        private bool IsAllyPlayer(string playerId, string otherId) {
            Clan playerClan = storedData.FindClanByID(playerId);
            if (playerClan == null) return false;
            Clan otherClan = storedData.FindClanByID(otherId);
            if (otherClan == null) return false;
            if (playerClan.Alliances.Contains(otherClan.Tag)) return true;
            return false;
        }
        private List<string> GetClanAlliances(ulong playerId) => GetClanAlliances(playerId.ToString());
        private List<string> GetClanAlliances(string playerId) {
            Clan clan = storedData.FindClanByID(playerId);
            if (clan == null) return new List<string>();
            return new List<string>(clan.Alliances);
        }
#endregion
#region Clan
        [Serializable]
        public class Clan {
            public string Tag {
                get;
                set;
            }
            public string Description {
                get;
                set;
            }
            public string OwnerID {
                get;
                set;
            }
            public double CreationTime {
                get;
                set;
            }
            public double LastOnlineTime {
                get;
                set;
            }
            public Hash<string, Member> ClanMembers {
                get;
                set;
            }
            = new Hash<string, Member>();
            public Hash<string, MemberInvite> MemberInvites {
                get;
                set;
            }
            = new Hash<string, MemberInvite>();
            public HashSet<string> Alliances {
                get;
                set;
            }
            = new HashSet<string>();
            public Hash<string, double> AllianceInvites {
                get;
                set;
            }
            = new Hash<string, double>();
            public HashSet<string> IncomingAlliances {
                get;
                set;
            }
            = new HashSet<string>();
            public string TagColor {
                get;
                set;
            }
            = string.Empty;
            [JsonIgnore]
            public int OnlineCount {
                get;
                private set;
            }
            [JsonIgnore]
            public int ModeratorCount => ClanMembers.Count(x => x.Value.Role == Member.MemberRole.Moderator);
            [JsonIgnore]
            public int MemberCount => ClanMembers.Count;
            [JsonIgnore]
            public int MemberInviteCount => MemberInvites.Count;
            [JsonIgnore]
            public int AllianceCount => Alliances.Count;
            [JsonIgnore]
            public int AllianceInviteCount => AllianceInvites.Count;
            public Clan() {
            }
            public Clan(IPlayer player, string tag, string description) {
                this.Tag = tag;
                this.Description = description;
                CreationTime = LastOnlineTime = UnixTimeStampUTC();
                OwnerID = player.Id;
                ClanMembers.Add(player.Id, new Member(Member.MemberRole.Owner, player.Name));
                OnPlayerConnected(player);
            }
#region Connection
            internal void OnPlayerConnected(IPlayer player) {
                i
// ... [Code preview truncated due to length. Full source in attached file] ...

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