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

FREE LiveAdminChat : 1.2.3 1.2.3

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Rust;
using Oxide.Core;
using ConVar;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Ext.Discord.Builders;
using Oxide.Ext.Discord.Constants;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Libraries;
using Oxide.Ext.Discord.Clients;
using Oxide.Ext.Discord.Interfaces;
namespace Oxide.Plugins {
    [Info("Live Admin Chat", "Daemante", "1.2.3")]
    [Description("Allows players to open a live chat with admins on Discord")]
    public class LiveAdminChat : RustPlugin, IDiscordPlugin {
#region Variables
        public DiscordClient Client {
            get;
            set;
        }
        = null!;
        public DiscordGuild _discordGuild {
            get;
            private set;
        }
        = null!;
        public DiscordUser _discordBot {
            get;
            private set;
        }
        = null!;
        private PluginConfig _config {
            get;
            set;
        }
        = null!;
        private readonly ChannelMessagesRequest _messageRequest = new ChannelMessagesRequest {
            Limit = 50
        }
        ;
        private DiscordSubscriptions _subscriptions {
            get;
            set;
        }
        = null!;
        private string? serverName;
        private const string LastChatCloseTimesFilePath = "oxide/data/LiveAdminChatCooldowns.json";
        private Dictionary<string, int> _cooldownValues = new Dictionary<string, int>();
#endregion
#region Config
        public class PluginConfig {
            [JsonProperty(PropertyName = "Discord Bot Token")]
            public string ApiKey {
                get;
                set;
            }
            = string.Empty;
            [JsonProperty(PropertyName = "Discord Server ID")]
            public Snowflake GuildId {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Category ID")]
            public Snowflake CategoryID;
            [JsonProperty(PropertyName = "Transcript Channel ID")]
            public Snowflake TranscriptChannelID {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Mentioned Role IDs")]
            public List<string> MentionedRoleIDs {
                get;
                set;
            }
            = new List<string>();
            [JsonProperty(PropertyName = "Reply Command")]
            public string ReplyCommand = "reply";
            [JsonProperty(PropertyName = "Chat Prefix")]
            public string ChatPrefix = "ADMIN";
            [JsonProperty(PropertyName = "Steam Profile Icon")]
            public string SteamProfileIcon = "";
            [JsonProperty(PropertyName = "Default Close Reason")]
            public string DefaultCloseReason = "Closed by Admin";
            [JsonProperty(PropertyName = "Show Admin Username")]
            public Boolean ShowAdminUsername = false;
            [JsonProperty(PropertyName = "Close On Disconnect")]
            public bool CloseOnDisconnect {
                get;
                set;
            }
            = false;
            [JsonProperty(PropertyName = "Chat Command")]
            public string ChatCommand = "adminchat";
            [JsonProperty(PropertyName = "Chat Cooldown (minutes)")]
            public int ChatCooldownMinutes {
                get;
                set;
            }
            = 5;
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<PluginConfig>();
                if (_config == null) {
                    throw new Exception();
                }
                SaveConfig();
            }
            catch {
                PrintError("Your configuration file contains an error.Using default configuration values.");
                LoadDefaultConfig();
            }
        }
        protected override void LoadDefaultConfig() {
            PrintWarning("Creating a new configuration file.");
            _config = new PluginConfig {
                ApiKey = "", GuildId = default, CategoryID = default, TranscriptChannelID = default, SteamProfileIcon = "", MentionedRoleIDs = new List<string> {
                    "1234567890", "0987654321"
                }
                , ReplyCommand = "reply", ChatPrefix = "ADMIN", ShowAdminUsername = false, CloseOnDisconnect = false, DefaultCloseReason = "Closed by admin", ChatCommand = "adminchat", ChatCooldownMinutes = 5,
            }
            ;
            SaveConfig();
        }
        protected override void SaveConfig() {
            Config.WriteObject(_config, true);
        }
#endregion
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["LiveChatNotAvailable"]
                = "[#FFFF00]/{0} is not available yet.[/#]", ["LiveChatSuccess"] = "[#00C851]Your request for an admin has been sent.[/#]", ["LiveChatAlreadyCalled"] = "[#ff4444]Please wait, your chat request is already in progress.[/#]", ["LiveChatMessageLayout"] = "[#00C851]Live Admin Chat[/#] - <size=11>[#dadada]Reply by typing:[/#] [#00C851]/{1} <message>[/#]</size>\n{0}", ["PlayerOffline"] = "Player is currently offline; message was not sent.", ["PlayerConnected"] = "**{0}** has connected to the server.", ["PlayerDisconnected"] = "**{0}** has disconnected from the server.", ["ReplyNotAvailable"] = "[#FFFF00]/{0} is not available yet.[/#]", ["ReplyCommandUsage"] = "[#FFFF00]Usage: /{0} [message][/#]", ["ReplyNoLiveChatInProgress"] = "[#FFFF00]You have no live chat in progress.[/#]", ["ReplyWaitForAdminResponse"] = "[#ff4444]Wait until someone responds before sending another message.[/#]", ["ReplyMessageSent"] = "[#00C851]Your message has been sent.[/#]\n{0}: {1}", ["ChatClosed"] = "[#FFFF00]The live admin chat has ended.[/#]", ["NoPermission"] = "[#FFFF00]You do not have permission to use /{0}.[/#]", ["ChatOnCooldown"] = "[#FFFF00]You must wait {0} minute(s) before starting a new chat.[/#]"
            }
            , this);
        }
        private string GetTranslation(string key, string? id = null, params object[] args) {
            if (covalence != null) {
                return covalence.FormatText(string.Format(lang.GetMessage(key, this, id), args));
            }
            else {
                return string.Format(lang.GetMessage(key, this, id), args);
            }
        }
#endregion
#region Initialization & Setup
        private void Init() {
            _subscriptions = GetLibrary<DiscordSubscriptions>();
            permission.RegisterPermission("liveadminchat.use", this);
            permission.RegisterPermission("liveadminchat.bypasscooldown", this);
            AddCovalenceCommand(_config.ChatCommand, "LiveChatCommand");
            AddCovalenceCommand(_config.ReplyCommand, "ReplyCommand");
            CheckForCooldownsFile();
            CheckAndRemoveExpiredCooldowns();
        }
        private void OnServerInitialized() {
            if (string.IsNullOrEmpty(_config.ApiKey)) {
                PrintWarning("Discord Bot Token is not set.Check your config and reload the plugin.");
                return;
            }
            try {
                Client.Connect(_config.ApiKey, GatewayIntents.Guilds | GatewayIntents.GuildMembers | GatewayIntents.GuildMessages | GatewayIntents.MessageContent);
            }
            catch (Exception ex) {
                PrintError($"Failed to connect Discord client: {ex.Message}");
            }
            serverName = ConVar.Server.hostname;
        }
        [HookMethod(DiscordExtHooks.OnDiscordClientCreated)]
        private void OnDiscordClientCreated() {
            if (Client == null) {
                PrintError("Discord client failed to initialize.");
                return;
            }
        }
        [HookMethod(DiscordExtHooks.OnDiscordGatewayReady)]
        private void OnDiscordGatewayReady(GatewayReadyEvent ready) {
            if (ready == null) {
                PrintError("Gateway is not ready.");
                return;
            }
            else {
                PrintWarning("Gateway is connected.");
            }
            if (Client == null) {
                PrintError("Discord client initialization failed.");
                return;
            }
            else {
                PrintWarning("Discord client has been initialized.");
            }
            if (Client?.Bot?.Application == null) {
                PrintError("Discord client, bot, or application is null.");
                return;
            }
            else {
                PrintWarning($"Bot has connected successfully.");
            }
            if (Client.Bot.Application.Flags.HasValue && !Client.Bot.Application.Flags.Value.HasFlag(ApplicationFlags.GatewayGuildMembersLimited)) {
                PrintError($"Bot does not have 'Server Members Intent' privileges.");
                return;
            }
            else {
                PrintWarning($"Bot has 'Server Members Intent' privileges.");
            }
            if (Client.Bot.Application.Flags.HasValue && !Client.Bot.Application.Flags.Value.HasFlag(ApplicationFlags.GatewayMessageContentLimited)) {
                PrintError($"Bot does not have 'Message Content Intent' privileges.");
                return;
            }
            else {
                PrintWarning($"Bot has 'Message Content Intent' privileges.");
            }
            if (Client.Bot.Application.Flags.HasValue && !Client.Bot.Application.Flags.Value.HasFlag(ApplicationFlags.GatewayPresenceLimited)) {
                PrintError($"Bot does not have 'Presence Intent' privileges.");
            }
            else {
                PrintWarning($"Bot has 'Presence Intent' privileges.");
            }
            DiscordGuild? guild = null;
            if (ready.Guilds.Count == 1 && !_config.GuildId.IsValid()) {
                guild = ready.Guilds.Values.FirstOrDefault();
            }
            if (guild == null && _config.GuildId.IsValid()) {
                guild = ready.Guilds[_config.GuildId];
            }
            if (guild == null) {
                PrintError("Failed to find a matching guild for the Discord Server ID provided in the config.");
                return;
            }
            else {
                PrintWarning($"Found server: {_config.GuildId}.");
            }
            if (ready.Guilds == null || ready.Guilds.Count == 0) {
                PrintError("Your bot was not found in any discord servers.Please invite it to a server and reload the plugin.");
                return;
            }
            else {
                PrintWarning($"Bot was found in server: {_config.GuildId}.");
            }
            _discordGuild = guild;
            _discordBot = Client.Bot.BotUser;
            DiscordChannel category = _discordGuild.Channels[_config.CategoryID];
            if (category == null || category.Type != ChannelType.GuildCategory) {
                PrintError($"Category with ID \"{_config.CategoryID}\" doesn't exist.Check your config and reload the plugin.");
                return;
            }
            else {
                PrintWarning($"Found category with ID: {_config.CategoryID}.");
            }
            DiscordChannel transcriptChannel = null;
            if (!string.IsNullOrEmpty(_config.TranscriptChannelID)) {
                transcriptChannel = _discordGuild.Channels[_config.TranscriptChannelID];
            }
            else {
                PrintError("Transcript channel ID is not set in the config.Bot will not create transcripts.");
            }
            if (transcriptChannel == null || transcriptChannel.Type != ChannelType.GuildText) {
                PrintError($"Transcript channel with ID \"{_config.TranscriptChannelID}\" doesn't exist.Bot will not create transcripts.");
            }
            else {
                PrintWarning($"Found transcript channel with ID: {_config.TranscriptChannelID}.");
            }
            foreach (DiscordChannel channel in _discordGuild.Channels.Values) {
                if (channel.ParentId == _config.CategoryID) {
                    SubscribeToChannel(channel);
                }
            }
            PrintWarning($"Bot is ready to start chatting.");
        }
#endregion
#region Methods
        [HookMethod("StartAdminChat")]
        public bool StartAdminChat(string playerID) {
            BasePlayer? player = GetPlayerByID(playerID);
            if (player == null) {
                PrintError($"Player with ID {playerID} wasn't found!");
                return false;
            }
            string channelName = playerID;
            DiscordChannel existingChannel = _discordGuild.GetChannel(channelName);
            if (existingChannel != null) {
                PrintError($"Player {playerID} already has an opened chat!");
                return false;
            }
            try {
                var newChannel = new ChannelCreate {
                    Name = channelName, Type = ChannelType.GuildText, ParentId = _config.CategoryID, DefaultAutoArchiveDuration = 1440
                }
                ;
                _discordGuild.CreateChannel(Client, newChannel).Then(channelTask => {
                    DiscordChannel channel = channelTask;
                    var builder = new MessageComponentBuilder().AddLinkButton("View steam profile", $"https://steamcommunity.com/profiles/{playerID}");
                    var createMessage = new MessageCreate {
                        Content = $"{string.Join(" ", _config.MentionedRoleIDs.Select(roleId => $"<@& {
                            roleId
                        }
                        >"))}\n\n**{serverName}\nNew chat opened for Steam64ID: {playerID}\nYou are now chatting with player: {GetPlayerByID(playerID)?.displayName}\n\nReply with '!close' to end the chat.\nYou can supply a reason by typing anything you want after '!close'\nExample: !close Banned cheater.\n\nReply with '!cooldown' to set a cooldown period in minutes for the player.\nExample: !cooldown 60**\n\n", Components = builder.Build()
                    }
                    ;
                    channel.CreateMessage(Client, createMessage);
                }
                ).Catch(exception => {
                    PrintError($"Failed to create channel: {exception.Message}");
                }
                );
                return true;
            }
            catch (Exception ex) {
                PrintError($"Error in StartAdminChat: {ex.Message}");
                return false;
            }
        }
        [HookMethod("StopAdminChat")]
        public void StopAdminChat(string playerID, string reason = null) {
            DiscordChannel channel = _discordGuild.GetChannel(playerID);
            if (channel == null) return;
            DeleteChannel(channel, reason);
        }
        private bool IsLiveChatChannel(DiscordChannel channel) {
            return channel.ParentId == _config.CategoryID && (!_config.TranscriptChannelID.IsValid() || channel.Id != _config.TranscriptChannelID);
        }
        private void DeleteChannel(DiscordChannel channel, string reason) {
            if (channel == null) {
                PrintError("Channel is null.Unable to delete the channel.");
                return;
            }
            if (!IsLiveChatChannel(channel)) {
                return;
            }
            if (string.IsNullOrEmpty(reason)) {
                reason = _config.DefaultCloseReason;
            }
            if (_discordGuild == null) {
                PrintError("Discord guild is not initialized");
                return;
            }
            channel.CreateMessage(Client, "Closing the chat in 5 seconds...").Then(messageTask => {
                SendTranscript(channel, reason);
                timer.Once(5f, () => {
                    channel.Delete(Client).Then(deleteTask => {
                        PrintToConsole($"Successfully deleted channel '{channel.Name}'");
                        SendMessageToPlayerID(channel.Name, $"The chat has been closed by an admin.\nTicket ID: {channel.Name} \nReason: {reason}");
                        string playerID = channel.Name;
                        UpdateLastChatCloseTime(playerID);
                    }
                    ).Catch(exception => {
                        PrintError($"Failed to delete channel '{channel.Name}': {exception.Message}");
                    }
                    );
                }
                );
            }
            ).Catch(exception => {
                PrintError($"Failed to send closing message: {exception.Message}");
            }
            );
        }
        private void SubscribeToChannel(DiscordChannel channel, string reason = null) {
            string channelName = channel.Name;
            if (channelName.Length <= 2) {
                PrintError($"Invalid channel name: {channelName}");
                return;
            }
            if (channel == null) {
                PrintError("Cannot subscribe to null channel");
                return;
            }
            if (_subscriptions == null) {
                PrintError("Discord subscriptions not initialized");
                return;
            }
            _subscriptions.AddChannelSubscription(Client, channel.Id, message => {
                if (message.Author.Id == _discordBot.Id) {
                    return;
                }
                if (message.Content.StartsWith("!close")) {
                    string reason = message.Content.Length > 6 ? message.Content.Substring(7).Trim() : null;
                    string playerID = channel.Name;
                    StopAdminChat(playerID, reason);
                    return;
                }
                if (message.Content.StartsWith("!cooldown")) {
                    string[] parts = message.Content.Split(' ', StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length > 1) {
                        string cooldownMinutes = parts[1];
                        string playerID = channel.Name;
                        SetCooldown(playerID, cooldownMinutes);
                        var createMessage = new MessageCreate {
                            Content = $"Cooldown of {cooldownMinutes} minutes has been set for player {playerID}."
                        }
                        ;
                        channel.CreateMessage(Client, createMessage);
                        return;
                    }
                }
                string messageContent = _config.ChatPrefix + ": " + "";
                if (_config.ShowAdminUsername) {
                    messageContent += "[#c9c9c9]" + message.Author.Username + ": [/#]";
                }
                messageContent += message.Content;
                // message.CreateReaction(Client, "✅");
                if (!SendMessageToPlayerID(channelName, GetTranslation("LiveChatMessageLayout", channelName, messageContent, _config.ReplyCommand))) {
                    channel.CreateMessage(Client, new MessageCreate {
                        Content = GetTranslation("PlayerOffline")
                    }
                    );
                }
            }
            );
        }
        private BasePlayer? GetPlayerByID(string ID) {
            try {
                return BasePlayer.FindByID(Convert.ToUInt64(ID));
            }
            catch {
                return null;
            }
        }
        private bool SendMessageToPlayerID(string playerID, string message) {
            if (string.IsNullOrEmpty(playerID)) {
                PrintError("PlayerID cannot be null or empty");
                return false;
            }
            if (string.IsNullOrEmpty(message)) {
                PrintError("Message cannot be null or empty");
                return false;
            }
            try {
                if (!ulong.TryParse(playerID, out ulong steamId)) {
                    PrintError($"Invalid player ID format: {playerID}");
                    return false;
                }
                BasePlayer player = BasePlayer.FindByID(steamId);
                if (player == null) return false;
                player.Command("chat.add", (int)Chat.ChatChannel.Server, _config.SteamProfileIcon, message);
                return true;
            }
            catch (Exception ex) {
                PrintError($"Error in SendMessageToPlayerID: {ex.Message}");
                return false;
            }
        }
        private void SendTranscript(DiscordChannel channel, string reason) {
            if (channel == null) {
                PrintError("Cannot send transcript: channel is null");
                return;
            }
            if (!_config.TranscriptChannelID.IsValid()) {
                PrintError("Invalid transcript channel ID in configuration");
                return;
            }
            try {
                var transcriptChannel = _discordGuild.GetChannel(_config.TranscriptChannelID);
                channel.GetMessages(Client, new ChannelMessagesRequest {
                    Limit = 100
                }
                ).Then(messages => {
                    if (messages == null || !messages.Any()) return;
                    var messageList = messages.ToList();
                    messageList.Reverse();
                    var transcriptBuilder = new System.Text.StringBuilder();
                    transcriptBuilder.AppendLine($"{serverName}");
                    transcriptBuilder.AppendLine($"Transcript for ticket: {channel.Name}");
                    transcriptBuilder.AppendLine($"Reason for closing: {reason}");
                    transcriptBuilder.AppendLine("```");
                    for (int i = 1; i < messageList.Count; i++) {
                        var msg = messageList[i];
                        transcriptBuilder.AppendLine($"{msg.Author.Username}: {msg.Content}");
                    }
                    transcriptBuilder.AppendLine("```");
                    var embed = new DiscordEmbed {
                        Title = $"Live Admin Chat", Description = transcriptBuilder.ToString(), Color = DiscordColor.Blue, Timestamp = DateTime.UtcNow
                    }
                    ;
                    var createMessage = new MessageCreate {
                        Embeds = new List<DiscordEmbed> {
                            embed
                        }
                    }
                    ;
                    transcriptChannel.CreateMessage(Client, createMessage).Then(message => {
                        PrintToConsole($"Successfully created transcript for channel '{channel.Name}'");
                    }
                    ).Catch(exception => {
                        PrintError($"Failed to create transcript message: {exception.Message}");
                    }
                    );
                    return;
                }
                ).Catch(exception => {
                    PrintError($"Failed to get messages for transcript: {exception.Message}");
                }
                );
            }
            catch (Exception ex) {
                PrintError($"Error in SendTranscript: {ex.Message}");
            }
        }
        private void SetCooldown(string playerID, string cooldownMinutes) {
            if (string.IsNullOrEmpty(cooldownMinutes.Trim())) {
                PrintError($"Invalid cooldown value: {cooldownMinutes.Trim()}");
                return;
            }
            if (!int.TryParse(cooldownMinutes.Trim(), out int cooldownMinutesInt)) {
                PrintError($"Invalid cooldown value: {cooldownMinutes.Trim()}");
                return;
            }
            DiscordChannel channel = _discordGuild.GetChannel(playerID);
            if (channel == null) {
                PrintError($"Channel with ID '{playerID}' doesn't exist.");
                return;
            }
            _cooldownValues[playerID] = cooldownMinutesInt;
            UpdateLastChatCloseTime(playerID);
        }
        private void CheckForCooldownsFile() {
            try {
                if (!File.Exists(LastChatCloseTimesFilePath)) {
                    File.WriteAllText(LastChatCloseTimesFilePath, "{}");
                    PrintWarning($"Created {LastChatCloseTimesFilePath} as it did not exist.");
                }
            }
            catch (Exception ex) {
                PrintError($"Failed to create {LastChatCloseTimesFilePath}: {ex.Message}");
            }
        }
        private Dictionary<string, DateTime> LoadLastChatCloseTimes() {
            try {
                if (File.Exists(LastChatCloseTimesFilePath)) {
                    var json = File.ReadAllText(LastChatCloseTimesFilePath);
                    return JsonConvert.DeserializeObject<Dictionary<string, DateTime>>(json) ?? new Dictionary<string, DateTime>();
                }
            }
            catch (Exception ex) {
                PrintError($"Failed to load last chat close times: {ex.Message}");
            }
            return new Dictionary<string, DateTime>();
        }
        private void SaveLastChatCloseTimes(Dictionary<string, DateTime> lastChatCloseTimes) {
            try {
                var json = JsonConvert.SerializeObject(lastChatCloseTimes, Formatting.Indented, new JsonSerializerSettings {
                    DateFormatString = "yyyy-MM-dd HH:mm"
                }
                );
                File.WriteAllText(LastChatCloseTimesFilePath, json);
            }
            catch (Exception ex) {
                PrintError($"Failed to save last chat close times: {ex.Message}");
            }
        }
        private void UpdateLastChatCloseTime(string playerID) {
            if (!File.Exists(LastChatCloseTimesFilePath)) {
                PrintError($"Cooldowns file not found at: {LastChatCloseTimesFilePath}");
                return;
            }
            var lastChatCloseTimes = LoadLastChatCloseTimes();
            if (_cooldownValues.TryGetValue(playerID, out int cooldownMinutes)) {
                lastChatCloseTimes[playerID] = DateTime.Now.AddMinutes(cooldownMinutes);
            }
            else if (!lastChatCloseTimes.ContainsKey(playerID)) {
                lastChatCloseTimes[playerID] = DateTime.Now.AddMinutes(_config.ChatCooldownMinutes);
            }
            SaveLastChatCloseTimes(lastChatCloseTimes);
        }
        private void CheckAndRemoveExpiredCooldowns() {
            if (!File.Exists(LastChatCloseTimesFilePath)) {
                PrintError($"Cooldowns file not found at: {LastChatCloseTimesFilePath}");
                return;
            }
            var lastChatCloseTimes = LoadLastChatCloseTimes();
            var expiredEntries = lastChatCloseTimes.Where(entry => entry.Value < DateTime.Now).ToList();
            foreach (var expiredEntry in expiredEntries) {
                lastChatCloseTimes.Remove(expiredEntry.Key);
            }
            SaveLastChatCloseTimes(lastChatCloseTimes);
        }
        [ConsoleCommand("liveadminchat.setcooldown")]
        private void ConsoleCommandSetCooldown(ConsoleSystem.Arg arg) {
            if (arg.Args == null || arg.Args.Length != 2) {
                Puts("Usage: liveadminchat.setcooldown <steam64id> <cooldown_minutes>");
                return;
            }
            string steam64id = arg.Args[0];
            if (!ulong.TryParse(steam64id, out _)) {
                Puts($"Invalid Steam64ID: {steam64id}");
                return;
            }
            if (!int.TryParse(arg.Args[1], out int cooldownMinutes) || cooldownMinutes <= 0) {
                Puts($"Invalid cooldown value: {arg.Args[1]}.Please provide a positive integer in minutes.");
                return;
            }
            string playerID = steam64id;
            _cooldownValues[playerID] = cooldownMinutes;
            var lastChatCloseTimes = LoadLastChatCloseTimes();
            lastChatCloseTimes[playerID] = DateTime.Now.AddMinutes(cooldownMinutes);
            SaveLastChatCloseTimes(lastChatCloseTimes);
            Puts($"Cooldown of {cooldownMinutes} minutes has been set for player: {steam64id}.");
        }
        [ConsoleCommand("liveadminchat.removecooldown")]
        private void ConsoleCommandRemoveCooldown(ConsoleSystem.Arg arg) {
            if (arg.Args == null || arg.Args.Length != 1) {
                Puts("Usage: liveadminchat.removecooldown <steam64id>");
                return;
            }
            string steam64id = arg.Args[0];
            if (!ulong.TryParse(steam64id, out _)) {
                Puts($"Invalid Steam64ID: {steam64id}");
                return;
            }
            string playerID = steam64id;
            _cooldownValues.Remove(playerID);
            var lastChatCloseTimes = LoadLastChatCloseTimes();
            bool removed = lastChatCloseTimes.Remove(playerID);
            SaveLastChatCloseTimes(lastChatCloseTimes);
            if (removed) {
                Puts($"Cooldown has been removed for player: {steam64id}.");
            }
            else {
                Puts($"No cooldown was set for player {steam64id}.");
            }
        }
        [ConsoleCommand("liveadminchat.listcooldowns")]
        private void ConsoleCommandListCooldowns(ConsoleSystem.Arg arg) {
            var lastChatCloseTimes = LoadLastChatCloseTimes();
            if (lastChatCloseTimes.Count == 0) {
                Puts("No active cooldowns found.");
                return;
            }
            Puts("Current active cooldowns:");
            Puts("------------------------");
            foreach (var cooldown in lastChatCloseTimes) {
                TimeSpan remainingTime = cooldown.Value - DateTime.Now;
                if (remainingTime.TotalMinutes > 0) {
                    Puts($"Steam64ID: {cooldown.Key}");
                    Puts($"Expires: {cooldown.Value:yyyy-MM-dd HH:mm:ss}");
                    Puts($"Remaining: {Math.Ceiling(remainingTime.TotalMinutes)} minutes");
                    Puts("------------------------");
                }
            }
        }
#endregion
#region Events
        [HookMethod(DiscordExtHooks.OnDiscordGuildChannelCreated)]
        private void OnDiscordGuildChannelCreated(DiscordChannel channel) {
            if (channel.ParentId == _config.CategoryID) SubscribeToChannel(channel);
        }
        [HookMethod(DiscordExtHooks.OnDiscordGuildChannelDeleted)]
        private void OnDiscordGuildChannelDeleted(DiscordChannel channel) {
            if (channel.ParentId == _config.CategoryID) {
                string channelName = channel.Name;
                if (channelName.Length != 17) return;
                SendMessageToPlayerID(channelName, GetTranslation("ChatClosed", channelName));
            }
        }
        [HookMethod("OnPlayerConnected")]
        private void OnPlayerConnected(BasePlayer player) {
            if (player == null) return;
            DiscordChannel? channel = _discordGuild?.GetChannel(player.UserIDString);
            if (channel != null) {
                try {
                    channel.CreateMessage(Client, new MessageCreate {
                        Content = GetTranslation("PlayerConnected", player.UserIDString, player.displayName)
                    }
                    );
                }
                catch (Exception ex) {
                    PrintError($"Failed to send player connection message: {ex.Message}");
                }
            }
        }
        [HookMethod("OnPlayerDisconnected")]
        private void OnPlayerDisconnected(BasePlayer player) {
            if (player == null) return;
            DiscordChannel? channel = _discordGuild?.GetChannel(player.UserIDString);
            if (channel != null) {
                try {
                    channel.CreateMessage(Client, new MessageCreate {
                        Content = GetTranslation("PlayerDisconnected", player.UserIDString, player.displayName)
                    }
                    );
                }
                catch (Exception ex) {
                    PrintError($"Failed to send player disconnection message: {ex.Message}");
                }
            }
            if (_config.CloseOnDisconnect) {
                StopAdminChat(player.UserIDString);
            }
        }
#endregion
#region Commands
        [ChatCommand("adminchat")]
        private void LiveChatCommand(IPlayer player, string command, string[] args) {
            if (Client == null) {
                player.Reply(GetTranslation("LiveChatNotAvailable", player.Id));
                PrintError("Discord client is null");
                return;
            }
            if (!Client.IsConnected()) {
                player.Reply(GetTranslation("LiveChatNotAvailable", player.Id));
                PrintError("Discord client is not connected");
                return;
            }
            if (!player.HasPermission("liveadminchat.use")) {
                player.Reply(GetTranslation("NoPermission", player.Id));
                PrintWarning("Player does not have permission.");
                return;
            }
            if (_discordGuild == null) {
                player.Reply(GetTranslation("LiveChatNotAvailable", player.Id));
                PrintError("Discord guild is null.");
                return;
            }
            bool hasBypassPermission = player.HasPermission("liveadminchat.bypasscooldown");
            if (!hasBypassPermission) {
                var lastChatCloseTimes = LoadLastChatCloseTimes();
                if (lastChatCloseTimes.TryGetValue(player.Id, out DateTime cooldownEndTime)) {
                    if (cooldownEndTime > DateTime.Now) {
                        int remainingMinutes = (int)Math.Ceiling((cooldownEndTime - DateTime.Now).TotalMinutes);
                        SendMessageToPlayerID(player.Id, GetTranslation("ChatOnCooldown", player.Id, remainingMinutes));
                        return;
                    }
                }
            }
            try {
                bool chatStarted = StartAdminChat(player.Id);
                if (!chatStarted) {
                    SendMessageToPlayerID(player.Id, GetTranslation("LiveChatAlreadyCalled", player.Id) );
                }
                else {
                    SendMessageToPlayerID(player.Id, GetTranslation("LiveChatSuccess", player.Id) );
                }
            }
            catch (Exception ex) {
                PrintError($"Error in LiveChatCommand: {ex.Message}");
                player.Reply("An error occurred while processing your request.");
            }
        }
        private void ReplyCommand(IPlayer player, string command, string[] args) {
            if (_discordGuild == null) {
                player.Reply(GetTranslation("ReplyNotAvailable", player.Id, _config.ReplyCommand));
                return;
            }
            if (args.Length < 1) {
                player.Reply(GetTranslation("ReplyCommandUsage", player.Id, _config.ReplyCommand));
                return;
            }
            DiscordChannel replyChannel = _discordGuild.GetChannel(player.Id);
            string sentMessage = string.Join(" ", args);
            if (replyChannel == null) {
                SendMessageToPlayerID(player.Id, GetTranslation("ReplyNoLiveChatInProgress", player.Id));
                return;
            }
            replyChannel.GetMessages(Client, _messageRequest).Then(messagesTask => {
                var messages = messagesTask;
                if (messages.Count < 2) {
                    SendMessageToPlayerID(player.Id, GetTranslation("ReplyWaitForAdminResponse", player.Id));
                    return;
                }
                DateTime now = DateTime.Now;
                replyChannel.CreateMessage(Client, new MessageCreate {
                    Content = $"{player.Name}: {sentMessage}"
                }
                );
                SendMessageToPlayerID(player.Id, GetTranslation("ReplyMessageSent", player.Id, player.Name, sentMessage));
            }
            ).Catch(exception => {
                PrintError($"Failed to get messages: {exception.Message}");
            }
            );
        }
#endregion
    }
}

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