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

FREE DiscordSignLogger : 1.0.10 1.0.10

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//Reference: System.Drawing
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Ext.Discord.Builders;
using Oxide.Ext.Discord.Constants;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using Oxide.Ext.Discord.Clients;
using Oxide.Ext.Discord.Connections;
using Oxide.Ext.Discord.Interfaces;
using UnityEngine;

using Color = System.Drawing.Color;
using Graphics = System.Drawing.Graphics;
using Star = ProtoBuf.PatternFirework.Star;

//DiscordSignLogger created with PluginMerge v(1.0.5.0) by MJSU @ https://github.com/dassjosh/Plugin.Merge
namespace Oxide.Plugins
{
    [Info("Discord Sign Logger", "MJSU", "1.0.10")]
    [Description("Logs Sign / Firework Changes To Discord")]
    public partial class DiscordSignLogger : RustPlugin, IDiscordPlugin
    {
        #region Plugins\DiscordSignLogger.Fields.cs
        [PluginReference] private Plugin RustTranslationAPI, SignArtist;
        
        public DiscordClient Client { get; set; }
        
        private PluginConfig _pluginConfig;
        private PluginData _pluginData;
        private PluginButtonData _buttonData;
        
        public const string CommandPrefix = "DSL ";
        private const string AccentColor = "#de8732";
        
        private readonly MessageCreate _actionMessage = new MessageCreate
        {
            AllowedMentions = new AllowedMentions
            {
                AllowedTypes = new List<AllowedMentionTypes>(),
                Roles = new List<Snowflake>(),
                Users = new List<Snowflake>()
            }
        };
        
        private readonly StringBuilder _sb = new StringBuilder();
        private readonly StringBuilder _actions = new StringBuilder();
        public readonly Hash<UnityEngine.Color, Brush> FireworkBrushes = new Hash<UnityEngine.Color, Brush>();
        private readonly Hash<NetworkableId, SignageUpdate> _updates = new  Hash<NetworkableId, SignageUpdate>();
        private readonly Hash<string, string> _prefabNameLookup = new Hash<string, string>();
        
        private DiscordChannel _actionChannel;
        
        private ILogEvent _log;
        private DiscordInteraction _interaction;
        private GuildMember _activeMember;
        public int FireworkImageSize;
        public int FireworkHalfImageSize;
        public int FireworkCircleSize;
        
        private readonly object _true = true;
        private readonly object _false = false;
        
        public static DiscordSignLogger Instance;
        #endregion

        #region Plugins\DiscordSignLogger.Setup.cs
        private void Init()
        {
            Instance = this;
            
            UnsubscribeAll();
            
            _pluginConfig.ReplaceImage.TextColor = _pluginConfig.ReplaceImage.TextColor.Replace("#", "");
            _pluginConfig.ReplaceImage.BodyColor = _pluginConfig.ReplaceImage.BodyColor.Replace("#", "");
            
            _pluginData = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
            _buttonData = Interface.Oxide.DataFileSystem.ReadObject<PluginButtonData>(Name + "_Buttons");
            
            List<int> activeHash = new List<int>();
            foreach (SignMessage message in _pluginConfig.SignMessages)
            {
                foreach (ImageMessageButtonCommand command in message.Commands)
                {
                    command.SetCommandId();
                    activeHash.Add(command.CommandId);
                    _buttonData.AddOrUpdate(command);
                }
            }
            
            _buttonData.CleanupExpired(activeHash, _pluginConfig.DeleteButtonCacheAfter);
            SaveButtonData();
            
            _pluginData.CleanupExpired(_pluginConfig.DeleteLogDataAfter);
            SaveData();
        }
        
        protected override void LoadDefaultConfig()
        {
            PrintWarning("Loading Default Config");
        }
        
        protected override void LoadConfig()
        {
            base.LoadConfig();
            Config.Settings.DefaultValueHandling = DefaultValueHandling.Populate;
            _pluginConfig = AdditionalConfig(Config.ReadObject<PluginConfig>());
            Config.WriteObject(_pluginConfig);
        }
        
        private PluginConfig AdditionalConfig(PluginConfig config)
        {
            config.FireworkSettings = new FireworkSettings(config.FireworkSettings);
            config.ReplaceImage = new ReplaceImageSettings(config.ReplaceImage);
            config.ActionLog = new ActionLogConfig(config.ActionLog);
            config.SignMessages = config.SignMessages ?? new List<SignMessage>();
            
            if (config.SignMessages.Count == 0)
            {
                config.SignMessages.Add(new SignMessage(null));
            }
            else
            {
                for (int index = 0; index < config.SignMessages.Count; index++)
                {
                    config.SignMessages[index] = new SignMessage(config.SignMessages[index]);
                }
            }
            
            return config;
        }
        
        private void OnServerInitialized()
        {
            FireworkCircleSize = _pluginConfig.FireworkSettings.CircleSize;
            FireworkImageSize = _pluginConfig.FireworkSettings.ImageSize + FireworkCircleSize;
            FireworkHalfImageSize = _pluginConfig.FireworkSettings.ImageSize / 2;
            
            if (string.IsNullOrEmpty(_pluginConfig.DiscordApiKey))
            {
                PrintWarning("Please set the Discord Bot Token and reload the plugin");
                return;
            }
            
            if (PlaceholderAPI == null || !PlaceholderAPI.IsLoaded)
            {
                PrintError("Missing plugin dependency PlaceholderAPI: https://umod.org/plugins/placeholder-api");
                return;
            }
            
            if(PlaceholderAPI.Version < new VersionNumber(2, 2, 0))
            {
                PrintError("Placeholder API plugin must be version 2.2.0 or higher");
                return;
            }
            
            if (SignArtist != null && SignArtist.IsLoaded && SignArtist.Version < new VersionNumber(1, 4, 0))
            {
                PrintWarning("Sign Artist version is outdated and may not function correctly.Please update SignArtist @ https://umod.org/plugins/sign-artist to version 1.4.0 or higher");
            }
            
            if (RustTranslationAPI == null || !RustTranslationAPI.IsLoaded)
            {
                foreach (ItemDefinition def in ItemManager.itemList)
                {
                    BaseEntity entity = def.GetComponent<ItemModDeployable>()?.entityPrefab.Get().GetComponent<BaseEntity>();
                    if (entity is ISignage || entity is PatternFirework)
                    {
                        _prefabNameLookup[entity.ShortPrefabName] = def.displayName.translated;
                    }
                }
            }
            
            Client.Connect(new BotConnection()
            {
                Intents = GatewayIntents.Guilds,
                ApiToken = _pluginConfig.DiscordApiKey,
                LogLevel = _pluginConfig.ExtensionDebugging
            });
            
            if (SignArtist == null || !SignArtist.IsLoaded)
            {
                Unsubscribe(nameof(OnPlayerCommand));
            }
        }
        
        private void Unload()
        {
            SaveData();
            SaveButtonData();
            Instance = null;
        }
        #endregion

        #region Plugins\DiscordSignLogger.CoreHooks.cs
        private void OnImagePost(BasePlayer player, string url, bool raw, ISignage signage, uint textureIndex)
        {
            _updates[signage.NetworkID] = new SignageUpdate(player, signage, _pluginConfig.SignMessages, textureIndex, player == null, url);
        }
        
        private void OnSignUpdated(ISignage signage, BasePlayer player, int textureIndex = 0)
        {
            if (player == null)
            {
                _updates.Remove(signage.NetworkID);
                return;
            }
            
            if (signage.GetTextureCRCs()[textureIndex] == 0)
            {
                return;
            }
            
            SignageUpdate update = _updates[signage.NetworkID] ?? new SignageUpdate(player, signage, _pluginConfig.SignMessages, (uint)textureIndex, player == null);
            _updates.Remove(signage.NetworkID);
            if (update.IgnoreMessage)
            {
                return;
            }
            
            SendDiscordMessage(update);
        }
        
        private void OnItemPainted(PaintedItemStorageEntity entity, Item item, BasePlayer player, byte[] image)
        {
            if (entity._currentImageCrc == 0)
            {
                return;
            }
            
            PaintedItemUpdate update = new PaintedItemUpdate(player, entity, item, image, _pluginConfig.SignMessages, false);
            SendDiscordMessage(update);
        }
        
        private void OnFireworkDesignChanged(PatternFirework firework, ProtoBuf.PatternFirework.Design design, BasePlayer player)
        {
            if (design?.stars == null || design.stars.Count == 0)
            {
                return;
            }
            
            SendDiscordMessage(new FireworkUpdate(player, firework, _pluginConfig.SignMessages));
        }
        
        private object CanUpdateSign(BasePlayer player, BaseEntity entity)
        {
            if (!_pluginData.IsSignBanned(player))
            {
                return null;
            }
            
            Chat(player, LangKeys.BlockedMessage, GetFormattedDurationTime(_pluginData.GetRemainingBan(player)));
            
            //Client side the sign will still be updated if we block it here.We destroy the entity client side to force a redraw of the image.NextTick(() =>
            {
                entity.DestroyOnClient(player.Connection);
                entity.SendNetworkUpdate();
            });
            
            return _false;
        }
        
        private object OnFireworkDesignChange(PatternFirework firework, ProtoBuf.PatternFirework.Design design, BasePlayer player)
        {
            if (!_pluginData.IsSignBanned(player))
            {
                return null;
            }
            
            Chat(player, LangKeys.BlockedMessage, player, GetFormattedDurationTime(_pluginData.GetRemainingBan(player), player));
            return _true;
        }
        
        private object OnPlayerCommand(BasePlayer player, string cmd, string[] args)
        {
            if (!cmd.StartsWith("sil", StringComparison.OrdinalIgnoreCase))
            {
                return null;
            }
            
            if (!_pluginData.IsSignBanned(player))
            {
                return null;
            }
            
            Chat(player, LangKeys.BlockedMessage, GetFormattedDurationTime(_pluginData.GetRemainingBan(player)));
            
            return _true;
        }
        
        private void UnsubscribeAll()
        {
            Unsubscribe(nameof(OnImagePost));
            Unsubscribe(nameof(OnSignUpdated));
            Unsubscribe(nameof(OnFireworkDesignChanged));
            Unsubscribe(nameof(CanUpdateSign));
            Unsubscribe(nameof(OnFireworkDesignChange));
            Unsubscribe(nameof(OnPlayerCommand));
        }
        
        private void SubscribeAll()
        {
            Subscribe(nameof(OnSignUpdated));
            Subscribe(nameof(OnFireworkDesignChanged));
            Subscribe(nameof(CanUpdateSign));
            Subscribe(nameof(OnFireworkDesignChange));
            
            if (SignArtist != null && SignArtist.IsLoaded)
            {
                Subscribe(nameof(OnPlayerCommand));
                Subscribe(nameof(OnImagePost));
            }
        }
        #endregion

        #region Plugins\DiscordSignLogger.DiscordHooks.cs
        [HookMethod(DiscordExtHooks.OnDiscordGuildCreated)]
        private void OnDiscordGuildCreated(DiscordGuild guild)
        {
            bool subscribe = false;
            foreach (SignMessage message in _pluginConfig.SignMessages)
            {
                if (message.MessageChannel == null && message.ChannelId.IsValid())
                {
                    DiscordChannel channel = GetChannel(guild, message.ChannelId);
                    if (channel != null)
                    {
                        message.MessageChannel = channel;
                        subscribe = true;
                    }
                }
            }
            
            if (_pluginConfig.ActionLog.ChannelId.IsValid())
            {
                DiscordChannel channel = GetChannel(guild, _pluginConfig.ActionLog.ChannelId);
                if (channel != null)
                {
                    _actionChannel = channel;
                }
            }
            
            if (subscribe)
            {
                SubscribeAll();
                Puts($"{Title} Ready");
            }
        }
        
        [HookMethod(DiscordExtHooks.OnDiscordInteractionCreated)]
        private void OnDiscordInteractionCreated(DiscordInteraction interaction)
        {
            switch (interaction.Type)
            {
                case InteractionType.MessageComponent:
                HandleMessageComponentCommand(interaction);
                break;
            }
        }
        #endregion

        #region Plugins\DiscordSignLogger.DiscordInteractions.cs
        private void HandleMessageComponentCommand(DiscordInteraction interaction)
        {
            if (!interaction.Data.ComponentType.HasValue || interaction.Data.ComponentType.Value != MessageComponentType.Button)
            {
                return;
            }
            
            string buttonId = interaction.Data.CustomId;
            if (!buttonId.StartsWith(CommandPrefix))
            {
                return;
            }
            
            SignUpdateLog log = _pluginData.GetLog(interaction.Message.Id);
            if (log == null)
            {
                DisableAllButtons(interaction.Message);
                SendComponentUpdateResponse(interaction);
                CreateResponse(interaction,  Lang(LangKeys.DeletedLog, null, _pluginConfig.DeleteLogDataAfter));
                return;
            }
            
            buttonId = buttonId.Replace(CommandPrefix, string.Empty);
            int hash;
            if (!int.TryParse(buttonId, out hash))
            {
                DisableAllButtons(interaction.Message);
                SendComponentUpdateResponse(interaction);
                CreateResponse(interaction, Lang(LangKeys.DeletedLog, null, _pluginConfig.DeleteButtonCacheAfter));
                return;
            }
            
            ImageMessageButtonCommand command = _buttonData.Get(hash);
            if (command == null)
            {
                DisableAllButtons(interaction.Message);
                SendComponentUpdateResponse(interaction);
                CreateResponse(interaction, Lang(LangKeys.DeletedLog, null, _pluginConfig.DeleteButtonCacheAfter));
                return;
            }
            
            RunCommand(interaction, log, command);
        }
        
        public void RunCommand(DiscordInteraction interaction, SignUpdateLog data, ImageMessageButtonCommand button)
        {
            try
            {
                _log = data;
                _activeMember = interaction.Member;
                _interaction = interaction;
                
                if (button.RequirePermissions && !UserHasButtonPermission(interaction, button))
                {
                    CreateResponse(interaction, Lang(LangKeys.NoPermission));
                    return;
                }
                
                IPlayer logPlayer = data.Player;
                
                _actions.Clear();
                
                foreach (string buttonCommand in button.Commands)
                {
                    _sb.Clear();
                    _sb.Append(buttonCommand);
                    ParsePlaceholders(logPlayer, _sb);
                    string serverCommand = _sb.ToString();
                    covalence.Server.Command(serverCommand);
                    
                    if (_actionChannel != null)
                    {
                        if (_actions.Length != 0)
                        {
                            _actions.AppendLine();
                        }
                        _actions.Append(Lang(LangKeys.ActionMessage));
                        ParsePlaceholders(logPlayer, _actions);
                        _actions.Replace("{dsl.command}", serverCommand);
                    }
                }
                
                if (_actionChannel != null)
                {
                    _actionMessage.Content = _actions.ToString();
                    if (_pluginConfig.ActionLog.Buttons.Count != 0)
                    {
                        MessageComponentBuilder builder = new MessageComponentBuilder();
                        for (int index = 0; index < _pluginConfig.ActionLog.Buttons.Count; index++)
                        {
                            ActionMessageButtonCommand actionButton = _pluginConfig.ActionLog.Buttons[index];
                            if (actionButton.Commands.Count == 0)
                            {
                                continue;
                            }
                            
                            if (actionButton.Style == ButtonStyle.Link)
                            {
                                builder.AddLinkButton(actionButton.DisplayName, ParsePlaceholders(logPlayer, actionButton.Commands[0]));
                            }
                        }
                        
                        _actionMessage.Components = builder.Build();
                    }
                    
                    _actionChannel.CreateMessage(Client, _actionMessage);
                }
                
                if (!string.IsNullOrEmpty(button.PlayerMessage))
                {
                    BasePlayer player = logPlayer.Object as BasePlayer;
                    if (player != null && player.IsConnected)
                    {
                        Chat(player, button.PlayerMessage);
                    }
                }
                
                if (!string.IsNullOrEmpty(button.ServerMessage))
                {
                    _sb.Clear();
                    _sb.Append(button.ServerMessage);
                    ParsePlaceholders(logPlayer, _sb);
                    covalence.Server.Broadcast(_sb.ToString());
                }
                
                if (_pluginConfig.DisableDiscordButton)
                {
                    DisableButton(interaction.Message, interaction.Data.CustomId);
                }
                
                interaction.CreateResponse(Client, new InteractionResponse
                {
                    Type = InteractionResponseType.UpdateMessage,
                    Data = new InteractionCallbackData
                    {
                        Components = interaction.Message.Components
                    }
                });
            }
            finally
            {
                _log = null;
                _activeMember = null;
                _interaction = null;
            }
        }
        
        public bool UserHasButtonPermission(DiscordInteraction interaction, ImageMessageButtonCommand button)
        {
            for (int index = 0; index < button.AllowedRoles.Count; index++)
            {
                Snowflake role = button.AllowedRoles[index];
                if (interaction.Member.HasRole(role))
                {
                    return true;
                }
            }
            
            IPlayer player = interaction.Member.User.Player;
            for (int index = 0; index < button.AllowedGroups.Count; index++)
            {
                string group = button.AllowedGroups[index];
                if (permission.UserHasGroup(player.Id, group))
                {
                    return true;
                }
            }
            
            return false;
        }
        
        public void DisableButton(DiscordMessage message, string id)
        {
            for (int index = 0; index < message.Components.Count; index++)
            {
                ActionRowComponent row = message.Components[index];
                for (int i = 0; i < row.Components.Count; i++)
                {
                    BaseComponent component = row.Components[i];
                    if (component is ButtonComponent)
                    {
                        ButtonComponent button = (ButtonComponent)component;
                        if (button.CustomId == id)
                        {
                            button.Disabled = true;
                            return;
                        }
                    }
                }
            }
        }
        
        public void DisableAllButtons(DiscordMessage message)
        {
            for (int index = 0; index < message.Components.Count; index++)
            {
                ActionRowComponent row = message.Components[index];
                for (int i = 0; i < row.Components.Count; i++)
                {
                    BaseComponent component = row.Components[i];
                    if (component is ButtonComponent)
                    {
                        ButtonComponent button = (ButtonComponent)component;
                        button.Disabled = true;
                    }
                }
            }
        }
        
        private void SendComponentUpdateResponse(DiscordInteraction interaction)
        {
            interaction.CreateResponse(Client, new InteractionResponse
            {
                Type = InteractionResponseType.UpdateMessage,
                Data = new InteractionCallbackData
                {
                    Components = interaction.Message.Components
                }
            });
        }
        
        public void CreateResponse(DiscordInteraction interaction, string response)
        {
            interaction.CreateResponse(Client, new InteractionResponse
            {
                Type = InteractionResponseType.ChannelMessageWithSource,
                Data = new InteractionCallbackData
                {
                    Content = response,
                    Flags = MessageFlags.Ephemeral
                }
            });
        }
        #endregion

        #region Plugins\DiscordSignLogger.DiscordMethods.cs
        public void SendDiscordMessage(BaseImageUpdate update)
        {
            try
            {
                _log = update;
                SignUpdateLog log = new SignUpdateLog(update);
                for (int index = 0; index < update.Messages.Count; index++)
                {
                    SignMessage signMessage = update.Messages[index];
                    MessageConfig message = signMessage.MessageConfig;
                    
                    MessageCreate create = new MessageCreate();
                    if (!string.IsNullOrEmpty(message.Content))
                    {
                        create.Content = ParsePlaceholders(null, message.Content);
                    }
                    
                    if (message.Embeds.Count != 0)
                    {
                        create.Embeds = new List<DiscordEmbed>(message.Embeds.Count);
                        foreach (EmbedConfig config in message.Embeds)
                        {
                            create.Embeds.Add(BuildEmbed(update.Player, config, update));
                        }
                    }
                    
                    create.AddAttachment("image.png", update.GetImage(), "image/png", $"{update.DisplayName} Updated {update.Entity.ShortPrefabName} @{update.Entity.transform.position} On {DateTime.Now:f}");
                    
                    MessageComponentBuilder builder = new MessageComponentBuilder();
                    for (int i = 0; i < signMessage.Commands.Count; i++)
                    {
                        ImageMessageButtonCommand command = signMessage.Commands[i];
                        if (command.Commands.Count == 0)
                        {
                            continue;
                        }
                        
                        if (command.Style == ButtonStyle.Link)
                        {
                            builder.AddLinkButton(command.DisplayName, ParsePlaceholders(update.Player, command.Commands[0]));
                        }
                        else
                        {
                            builder.AddActionButton(command.Style, command.DisplayName, command.CommandCustomId);
                        }
                    }
                    
                    create.Components = builder.Build();
                    
                    signMessage.MessageChannel?.CreateMessage(Client, create).Then(discordMessage => { _pluginData.AddLog(discordMessage.Id, log); });
                }
            }
            finally
            {
                _log = null;
            }
        }
        
        private DiscordEmbed BuildEmbed(IPlayer player, EmbedConfig embed, BaseImageUpdate update)
        {
            DiscordEmbedBuilder builder = new DiscordEmbedBuilder();
            if (!string.IsNullOrEmpty(embed.Title))
            {
                builder.AddTitle(ParsePlaceholders(player, embed.Title));
            }
            
            if (!string.IsNullOrEmpty(embed.Description))
            {
                builder.AddDescription(ParsePlaceholders(player, embed.Description));
            }
            
            if (!string.IsNullOrEmpty(embed.Url))
            {
                builder.AddUrl(ParsePlaceholders(player, embed.Url));
            }
            
            if (!string.IsNullOrEmpty(embed.Image))
            {
                builder.AddImage(ParsePlaceholders(player, embed.Image));
            }
            
            if (!string.IsNullOrEmpty(embed.Thumbnail))
            {
                builder.AddThumbnail(ParsePlaceholders(player, embed.Thumbnail));
            }
            
            if (!string.IsNullOrEmpty(embed.Color))
            {
                builder.AddColor(embed.Color);
            }
            
            if (embed.Timestamp)
            {
                builder.AddNowTimestamp();
            }
            
            if (embed.Footer.Enabled)
            {
                if (string.IsNullOrEmpty(embed.Footer.Text) &&
                string.IsNullOrEmpty(embed.Footer.IconUrl))
                {
                    AddPluginInfoFooter(builder);
                }
                else
                {
                    string text = ParsePlaceholders(player, embed.Footer.Text);
                    string footerUrl = ParsePlaceholders(player, embed.Footer.IconUrl);
                    builder.AddFooter(text, footerUrl);
                }
            }
            
            foreach (EmbedFieldConfig field in embed.Fields)
            {
                builder.AddField(ParsePlaceholders(player, field.Title), ParsePlaceholders(player, field.Value), field.Inline);
            }
            
            if (update is SignageUpdate)
            {
                SignageUpdate signage = (SignageUpdate)update;
                if (!string.IsNullOrEmpty(signage.Url))
                {
                    builder.AddField(ParsePlaceholders(player, Lang(LangKeys.SignArtistTitle)), ParsePlaceholders(player, Lang(LangKeys.SignArtistValue)), true);
                }
            }
            
            return builder.Build();
        }
        
        private const string OwnerIcon = "https://i.postimg.cc/cLGQsP1G/Sign-3.png";
        
        private void AddPluginInfoFooter(DiscordEmbedBuilder embed)
        {
            embed.AddFooter($"{Title} V{Version} by {Author}", OwnerIcon);
        }
        #endregion

        #region Plugins\DiscordSignLogger.Commands.cs
        [ConsoleCommand("dsl.erase")]
        private void EraseCommand(ConsoleSystem.Arg arg)
        {
            if (!arg.IsAdmin)
            {
                return;
            }
            
            NetworkableId id = arg.GetEntityID(0);
            uint index = arg.GetUInt(1);
            BaseEntity entity = BaseNetworkable.serverEntities.Find(id) as BaseEntity;
            if (entity == null)
            {
                return;
            }
            
            if (entity is ISignage)
            {
                ISignage signage = (ISignage)entity;
                uint[] textures = signage.GetTextureCRCs();
                uint crc = textures[index];
                if (crc == 0)
                {
                    return;
                }
                FileStorage.server.RemoveExact(crc, FileStorage.Type.png, signage.NetworkID, index);
                textures[index] = 0;
                entity.SendNetworkUpdate();
                
                HandleReplaceImage(signage, index);
                return;
            }
            
            if (entity is PaintedItemStorageEntity)
            {
                PaintedItemStorageEntity item = (PaintedItemStorageEntity)entity;
                if (item._currentImageCrc != 0)
                {
                    FileStorage.server.RemoveExact(item._currentImageCrc, FileStorage.Type.png, item.net.ID, 0);
                    item._currentImageCrc = 0;
                    item.SendNetworkUpdate();
                }
            }
            
            if (entity is PatternFirework)
            {
                PatternFirework firework = (PatternFirework)entity;
                firework.Design?.Dispose();
                firework.Design = null;
                firework.SendNetworkUpdateImmediate();
            }
        }
        
        [ConsoleCommand("dsl.signblock")]
        private void BanCommand(ConsoleSystem.Arg arg)
        {
            if (!arg.IsAdmin)
            {
                return;
            }
            
            ulong playerId = arg.GetULong(0);
            float duration = arg.GetFloat(1);
            
            _pluginData.AddSignBan(playerId, duration);
            
            if (duration <= 0)
            {
                arg.ReplyWith($"{playerId} has been sign blocked permanently");
            }
            else
            {
                arg.ReplyWith($"{playerId} has been sign blocked for {GetFormattedDurationTime(TimeSpan.FromSeconds(duration))}");
            }
            
            SaveData();
        }
        
        [ConsoleCommand("dsl.signunblock")]
        private void UnbanCommand(ConsoleSystem.Arg arg)
        {
            if (!arg.IsAdmin)
            {
                return;
            }
            
            ulong playerId = arg.GetULong(0);
            _pluginData.RemoveSignBan(playerId);
            SaveData();
            arg.ReplyWith($"{playerId} has been unbanned");
        }
        
        private void HandleReplaceImage(ISignage signage, uint index)
        {
            if (_pluginConfig.ReplaceImage.Mode == ErasedMode.None || SignArtist == null || !SignArtist.IsLoaded)
            {
                return;
            }
            
            ReplaceImageSettings image = _pluginConfig.ReplaceImage;
            if (signage is Signage)
            {
                if (image.Mode == ErasedMode.Text)
                {
                    SignArtist.Call("API_SignText", null, signage, image.Message, image.FontSize, image.TextColor, image.BodyColor, index);
                }
                else if (!string.IsNullOrEmpty(image.Url))
                {
                    SignArtist.Call("API_SkinSign", null, signage, image.Url, _false, index);
                }
            }
            else if (signage is PhotoFrame)
            {
                if (!string.IsNullOrEmpty(image.Url))
                {
                    SignArtist.Call("API_SkinPhotoFrame", null, signage, image.Url);
                }
            }
            else if (signage is CarvablePumpkin)
            {
                if (!string.IsNullOrEmpty(image.Url))
                {
                    SignArtist.Call("API_SkinPumpkin", null, signage, image.Url);
                }
            }
        }
        #endregion

        #region Plugins\DiscordSignLogger.Helpers.cs
        public DiscordChannel GetChannel(DiscordGuild guild, Snowflake id)
        {
            return guild?.Channels[id] ?? guild?.Threads[id];
        }
        
        public IPlayer FindPlayerById(string id)
        {
            return covalence.Players.FindPlayerById(id);
        }
        
        public string Lang(string key, BasePlayer player = null)
        {
            return lang.GetMessage(key, this, player ? player.UserIDString : null);
        }
        
        public string Lang(string key, BasePlayer player = null, params object[] args)
        {
            try
            {
                return string.Format(lang.GetMessage(key, this, player ? player.UserIDString : null), args);
            }
            catch (Exception ex)
            {
                PrintError($"Lang Key '{key}' threw exception\n:{ex}");
                throw;
            }
        }
        
        public void Chat(BasePlayer player, string key) => PrintToChat(player, Lang(LangKeys.Chat, player, Lang(key, player)));
        public void Chat(BasePlayer player, string key, params object[] args) => PrintToChat(player, Lang(LangKeys.Chat, player, Lang(key, player, args)));
        
        public void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, _pluginData);
        public void SaveButtonData() => Interface.Oxide.DataFileSystem.WriteObject(Name + "_Buttons", _buttonData);
        #endregion

        #region Plugins\DiscordSignLogger.Lang.cs
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [LangKeys.Chat] = $"<color=#bebebe>[<color={AccentColor}>{Title}</color>] {{0}}</color>",
                [LangKeys.NoPermission] = "You do not have permission to perform this action",
                [LangKeys.KickReason] = "Inappropriate sign/firework image",
                [LangKeys.BanReason] = "Inappropriate sign/firework image",
                [LangKeys.BlockedMessage] = "You're not allowed to update this sign/firework because you have been blocked.Your block will expire in {0}.",
                [LangKeys.ActionMessage] = $"[{Title}] <@{{dsl.discord.user.id}}> ran command \"{{dsl.command}}\"",
                [LangKeys.DeletedLog] = "The log data for this message was not found.If it's older than {0} days then it may have been deleted.",
                [LangKeys.DeletedButtonCache] = "Button was not found in cache.If this message is older than {0} days then it may have been deleted.",
                [LangKeys.SignArtistTitle] = "Sign Artist URL:",
                [LangKeys.SignArtistValue] = "{dsl.signartist.url}",
                [LangKeys.Format.Day] = "day ",
                [LangKeys.Format.Days] = "days ",
                [LangKeys.Format.Hour] = "hour ",
                [LangKeys.Format.Hours] = "hours ",
                [LangKeys.Format.Minute] = "minute ",
                [LangKeys.Format.Minutes] = "minutes ",
                [LangKeys.Format.Second] = "second",
                [LangKeys.Format.Seconds] = "seconds",
                [LangKeys.Format.TimeField] = $"<color={AccentColor}>{{0}}</color> {{1}}"
                
            }, this);
            
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [LangKeys.Chat] = $"<color=#bebebe>[<color={AccentColor}>{Title}</color>] {{0}}</color>",
                [LangKeys.NoPermission] = "У вас нет разрешения на выполнение этого действия",
                [LangKeys.KickReason] = "Недопустимое изображение знака/фейерверка",
                [LangKeys.BanReason] = "Недопустимое изображение знака/фейерверка",
                [LangKeys.BlockedMessage] = "Возможность использовать изображения на знаке/феерверке для вас заблокирована.Разблокировка через {0}.",
                [LangKeys.ActionMessage] = $"[{Title}] <@{{dsl.discord.user.id}}> выполнил команду \"{{dsl.command}}\"",
                [LangKeys.DeletedLog] = "Данные журнала для этого сообщения не найдены.Если сообщение старше {0} дней, возможно, оно было удалено.",
                [LangKeys.DeletedButtonCache] = "Кнопка не найдена в кеше.Если сообщение старше {0} дней, возможно, оно было удалено.",
                [LangKeys.SignArtistTitle] = "Sign Artist URL:",
                [LangKeys.SignArtistValue] = "{dsl.signartist.url}",
                [LangKeys.Format.Day] = "день ",
                [LangKeys.Format.Days] = "дней ",
                [LangKeys.Format.Hour] = "час ",
                [LangKeys.Format.Hours] = "часов ",
                [LangKeys.Format.Minute] = "минуту ",
                [LangKeys.Format.Minutes] = "минут ",
                [LangKeys.Format.Second] = "секунду",
                [LangKeys.Format.Seconds] = "секунд",
                [LangKeys.Format.TimeField] = $"<color={AccentColor}>{{0}}</color> {{1}}"
            }, this, "ru");
        }
        
        private string GetFormattedDurationTime(TimeSpan time, BasePlayer player = null)
        {
            _sb.Clear();
            
            if (time.TotalDays >= 1)
            {
                BuildTime(_sb, time.Days == 1 ? LangKeys.Format.Day : LangKeys.Format.Days, player, time.Days);
            }
            
            if (time.TotalHours >= 1)
            {
                BuildTime(_sb, time.Hours == 1 ? LangKeys.Format.Hour : LangKeys.Format.Hours, player, time.Hours);
            }
            
            if (time.TotalMinutes >= 1)
            {
                BuildTime(_sb, time.Minutes == 1 ? LangKeys.Format.Minute : LangKeys.Format.Minutes, player, time.Minutes);
            }
            
            BuildTime(_sb, time.Seconds == 1 ? LangKeys.Format.Second : LangKeys.Format.Seconds, player, time.Seconds);
            
            return _sb.ToString();
        }
        
        private void BuildTime(StringBuilder sb, string key, BasePlayer player, int value)
        {
            sb.Append(Lang(LangKeys.Format.TimeField, player, value, Lang(key, player)));
        }
        #endregion

        #region Plugins\DiscordSignLogger.PlaceholderApi.cs
        #pragma warning disable CS0649
        [PluginReference] private Plugin PlaceholderAPI;
        #pragma warning restore CS0649
        private Action<IPlayer, StringBuilder, bool> _replacer;
        
        private string ParsePlaceholders(IPlayer player, string field)
        {
            _sb.Clear();
            _sb.Append(field);
            GetReplacer()?.Invoke(player, _sb, false);
            if (_sb.Length == 0)
            {
                _sb.Append("");
            }
            return _sb.ToString();
        }
        
        private void ParsePlaceholders(IPlayer player, StringBuilder sb)
        {
            GetReplacer()?.Invoke(player, sb, false);
        }
        
        private void OnPluginUnloaded(Plugin plugin)
        {
            if (plugin?.Name == "PlaceholderAPI")
            {
                _replacer = null;
            }
        }
        
        public string GetSignAristUrl()
        {
            SignageUpdate signage = _log as SignageUpdate;
            return signage?.Url ?? string.Empty;
        }
        
        private void OnPlaceholderAPIReady()
        {
            RegisterPlaceholder("dsl.entity.id", (player, s) =>
            {
                BaseEntity entity = _log.Entity;
                return entity ? entity.net?.ID.Value ?? 0 : 0;
                
            }, "Displays the entity ID");
            
            RegisterPlaceholder("dsl.entity.textureindex", (player, s) => _log?.TextureIndex ?? 0, "Displays the texture index");
            
            RegisterPlaceholder("dsl.entity.name", (player, s) =>
            {
                if (_log.ItemId != 0)
                {
                    return GetItemName(_log.ItemId);
                }
                
                BaseEntity entity = _log.Entity;
                return entity ? GetEntityName(entity) : "Entity Not Found";
            }, "Displays the entity item name");
            
            RegisterPlaceholder("dsl.entity.owner.id", (player, s) =>
            {
                BaseEntity entity = _log.Entity;
                return entity ? entity.OwnerID : 0;
            }, "Displays the entity Owner ID");
            
            RegisterPlaceholder("dsl.entity.owner.name", (player, s) =>
            {
                BaseEntity entity = _log.Entity;
                if (!entity)
                {
                    return "Unknown";
                }
                
                IPlayer owner = covalence.Players.FindPlayerById(entity.OwnerID.ToString());
                if (owner == null)
                {
                    return "Unknown";
                }
                
                BasePlayer ownerPlayer = (BasePlayer)owner.Object;
                return ownerPlayer ? ownerPlayer.displayName : owner.Name;
            }, "Displays the entity owner player name");
            
            RegisterPlaceholder("dsl.entity.position", (player, s) =>
            {
                BaseEntity entity = _log.Entity;
                if (!entity)
                {
                    if (string.IsNullOrEmpty(s))
                    {
                        return Vector3.zero;
                    }
                    
                    return 0f;
                }
                
                Vector3 pos = entity.transform.position;
                if (string.IsNullOrEmpty(s))
                {
                    return pos;
                }
                
                if (s.Equals("x", StringComparison.OrdinalIgnoreCase))
                {
                    return pos.x;
                }
                
                if (s.Equals("y", StringComparison.OrdinalIgnoreCase))
                {
                    return pos.y;
                }
                
                if (s.Equals("z", StringComparison.OrdinalIgnoreCase))
                {
                    return pos.z;
                }
                
                return pos;
            }, "Displays the position of the entity");
            
            RegisterPlaceholder("dsl.discord.user.id", (player, s) => _activeMember?.Id ?? default(Snowflake), "Discord user id who clicked the button");
            RegisterPlaceholder("dsl.discord.user.name", (player, s) => _activeMember?.DisplayName ?? "Unknown User", "Discord display name of user who clicked the button");
            RegisterPlaceholder("dsl.kick.reason", (player, s) => Lang(LangKeys.KickReason), "Kick Reason Lang Value");
            RegisterPlaceholder("dsl.ban.reason", (player, s) => Lang(LangKeys.BanReason), "Ban Reason Lang Value");
            RegisterPlaceholder("dsl.signartist.url", (player, s) => GetSignAristUrl(), "Sign Artist URL");
            RegisterPlaceholder("dsl.action.guild.id", (player, s) => _interaction?.GuildId ?? default(Snowflake), "Actioned Message Guild ID");
            RegisterPlaceholder("dsl.action.channel.id", (player, s) => _interaction?.ChannelId ?? default(Snowflake), "Actioned Message Channel ID");
            RegisterPlaceholder("dsl.action.message.id", (player, s) => _interaction.Message?.Id ?? default(Snowflake), "Actioned Message Message ID");
        }
        
        private void RegisterPlaceholder(string key, Func<IPlayer, string, object> action, string description = null)
        {
            if (IsPlaceholderApiLoaded())
            {
                PlaceholderAPI.Call("AddPlaceholder", this, key, action, description);
            }
        }
        
        private Action<IPlayer, StringBuilder, bool> GetReplacer()
        {
            if (!IsPlaceholderApiLoaded())
            {
                return _replacer;
            }
            
            return _replacer ?? (_replacer = PlaceholderAPI.Call<Action<IPlayer, StringBuilder, bool>>("GetProcessPlaceholders", 1));
        }
        
        private bool IsPlaceholderApiLoaded() => PlaceholderAPI != null && PlaceholderAPI.IsLoaded;
        #endregion

        #region Plugins\DiscordSignLogger.RustTranslationApi.cs
        public string GetEntityName(BaseEntity entity)
        {
            if (!entity)
            {
                return string.Empty;
            }
            
            if (RustTranslationAPI != null && RustTranslationAPI.IsLoaded)
            {
                string name = RustTranslationAPI.Call<string>("GetDeployableTranslation", lang.GetServerLanguage(), entity.ShortPrefabName);
                if (!string.IsNullOrEmpty(name))
                {
                    return name;
                }
            }
            
            return _prefabNameLookup[entity.ShortPrefabName] ?? entity.ShortPrefabName;
        }
        
        public string GetItemName(int itemId)
        {
            if (itemId == 0)
            {
                return string.Empty;
            }
            
            if (RustTranslationAPI != null && RustTranslationAPI.IsLoaded)
            {
                string name = RustTranslationAPI.Call<string>("GetItemTranslationByID", lang.GetServerLanguage(), itemId);
                if (!string.IsNullOrEmpty(name))
                {
                    return name;
                }
            }
            
            return ItemManager.FindItemDefinition(itemId).displayName.translated;
        }
        #endregion

        #region Configuration\BaseDiscordButton.cs
        public class BaseDiscordButton
        {
            [JsonProperty(PropertyName = "Button Display Name")]
            public string DisplayName { get; set; }
            
            [JsonConverter(typeof(StringEnumConverter))]
            [JsonProperty(PropertyName = "Button Style")]
            public ButtonStyle Style { get; set; }
            
            [JsonProperty(PropertyName = "Commands")]
            public List<string> Commands { get; set; }
            
            [JsonConstructor]
            public BaseDiscordButton()
            {
                
            }
            
            public BaseDiscordButton(BaseDiscordButton settings)
            {
                DisplayName = settings?.DisplayName ?? "Button Display Name";
                Style = settings?.Style ?? ButtonStyle.Primary;
                Commands = settings?.Commands ?? new List<string>();
            }
        }
        #endregion

        #region Configuration\FireworkSettings.cs
        public class FireworkSettings
        {
            [JsonProperty(PropertyName = "Image Size (Pixels)")]
            public int ImageSize { get; set; }
            
            [JsonProperty(PropertyName = "Circle Size (Pixels)")]
            public int CircleSize { get; set; }
            
            public FireworkSettings(FireworkSettings settings)
            {
                ImageSize = settings?.ImageSize ?? 25
// ... [Code preview truncated due to length. Full source in attached file] ...

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