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

FREE DiscordSignLogger : 3.0.0 3.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//Reference: System.Drawing
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Ext.Discord.Attributes;
using Oxide.Ext.Discord.Builders;
using Oxide.Ext.Discord.Cache;
using Oxide.Ext.Discord.Clients;
using Oxide.Ext.Discord.Connections;
using Oxide.Ext.Discord.Constants;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Extensions;
using Oxide.Ext.Discord.Interfaces;
using Oxide.Ext.Discord.Libraries;
using Oxide.Ext.Discord.Logging;
using Oxide.Ext.Discord.Types;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using UnityEngine;
using Color = System.Drawing.Color;
using Graphics = System.Drawing.Graphics;
using Star = ProtoBuf.PatternFirework.Star;
//DiscordSignLogger created with PluginMerge v(1.0.9.0) by MJSU @ https://github.com/dassjosh/Plugin.Merge
namespace Oxide.Plugins {
    [Info("Discord Sign Logger", "MJSU", "3.0.0")]
    [Description("Logs Sign / Firework Changes To Discord")]
    public partial class DiscordSignLogger : RustPlugin, IDiscordPlugin, IDiscordPool {
#region Plugins\DiscordSignLogger.Fields.cs
#pragma warning disable CS0649
        // ReSharper disable InconsistentNaming
        [PluginReference]
        private Plugin RustTranslationAPI, SignArtist;
        // ReSharper restore InconsistentNaming
#pragma warning restore CS0649
#pragma warning disable CS0649
        public DiscordClient Client {
            get;
            set;
        }
#pragma warning restore CS0649
        private PluginConfig _pluginConfig;
        private PluginData _pluginData;
        private const string CommandPrefix = "DSL_CMD";
        private const string ActionPrefix = "DSL_ACTION";
        private const string ModalPrefix = "DSL_MODAL";
        private const string PlayerMessage = "PLAYER_MESSAGE";
        private const string ServerMessage = "SERVER_MESSAGE";
        private const string AccentColor = "#de8732";
        private readonly MessageCreate _actionMessage = new() {
            AllowedMentions = AllowedMentions.None
        }
        ;
        public DiscordPluginPool Pool {
            get;
            set;
        }
        private readonly StringBuilder _sb = new();
        public readonly Hash<UnityEngine.Color, Brush> FireworkBrushes = new();
        private readonly Hash<NetworkableId, SignageUpdate> _updates = new();
        private readonly Hash<uint, string> _prefabNameCache = new();
        private readonly Hash<int, string> _itemNameCache = new();
        private readonly Hash<TemplateKey, SignMessage> _signMessages = new();
        private readonly Hash<ButtonId, ImageButton> _imageButtons = new();
        private DiscordChannel _actionChannel;
        private readonly DiscordPlaceholders _placeholders = GetLibrary<DiscordPlaceholders>();
        private readonly DiscordMessageTemplates _templates = GetLibrary<DiscordMessageTemplates>();
        private readonly DiscordButtonTemplates _buttonTemplates = GetLibrary<DiscordButtonTemplates>();
        private readonly DiscordCommandLocalizations _local = GetLibrary<DiscordCommandLocalizations>();
        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("#", "");
            HashSet<string> ids = new();
            foreach (SignMessage message in _pluginConfig.SignMessages) {
                if (ids.Add(message.MessageId.Name)) {
                    _signMessages[message.MessageId] = message;
                }
                else {
                    PrintWarning($"Duplicate Sign Message ID: '{message.MessageId.Name}'.Please check your config and correct the duplicate Sign Message ID's");
                }
            }
            ids.Clear();
            foreach (ImageButton button in _pluginConfig.Buttons) {
                if (ids.Add(button.ButtonId.Id)) {
                    _imageButtons[button.ButtonId] = button;
                }
                else {
                    PrintWarning($"Duplicate Button ID: '{button.ButtonId.Id}'.Please check your config and correct the duplicate Image Button ID's");
                }
            }
            _pluginData = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
            RegisterPlaceholders();
            RegisterTemplates();
        }
        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.SignMessages ??= new List<SignMessage>();
            config.PluginSettings = new PluginSettings(config.PluginSettings);
            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]);
                }
            }
            config.Buttons ??= new List<ImageButton> {
                new() {
                    ButtonId = new ButtonId("ERASE"), DisplayName = "Erase", Style = ButtonStyle.Primary, Commands = new List<string> {
                        $"dsl.erase {PlaceholderKeys.EntityId} {PlaceholderKeys.TextureIndex}"
                    }
                    , PlayerMessage = "An admin erased your sign for being inappropriate", ServerMessage = string.Empty, RequirePermissions = false, ConfirmModal = false, AllowedRoles = new List<Snowflake>(), AllowedGroups = new List<string>()
                }
                , new() {
                    ButtonId = new ButtonId("SIGN_BLOCK_24_HOURS"), DisplayName = "Sign Block (24 Hours)", Style = ButtonStyle.Primary, Commands = new List<string> {
                        "dsl.signblock {player.id} 86400"
                    }
                    , PlayerMessage = "You have been banned from updating signs for 24 hours.", ServerMessage = string.Empty, RequirePermissions = true, ConfirmModal = false, AllowedRoles = new List<Snowflake>(), AllowedGroups = new List<string>()
                }
                , new() {
                    ButtonId = new ButtonId("KILL_ENTITY"), DisplayName = "Kill Entity", Style = ButtonStyle.Secondary, Commands = new List<string> {
                        $"entid kill {PlaceholderKeys.EntityId}"
                    }
                    , PlayerMessage = "An admin killed your sign for being inappropriate", ServerMessage = string.Empty, RequirePermissions = true, ConfirmModal = false, AllowedRoles = new List<Snowflake>(), AllowedGroups = new List<string>()
                }
                , new() {
                    ButtonId = new ButtonId("KICK_PLAYER"), DisplayName = "Kick Player", Style = ButtonStyle.Danger, Commands = new List<string> {
                        $"kick {DefaultKeys.Player.Id} \"{PlaceholderKeys.PlayerMessage}\"", $"dsl.erase {PlaceholderKeys.EntityId} {PlaceholderKeys.TextureIndex}"
                    }
                    , PlayerMessage = string.Empty, ServerMessage = string.Empty, RequirePermissions = true, ConfirmModal = true, AllowedRoles = new List<Snowflake>(), AllowedGroups = new List<string>()
                }
                , new() {
                    ButtonId = new ButtonId("BAN_PLAYER"), DisplayName = "Ban Player", Style = ButtonStyle.Danger, Commands = new List<string> {
                        $"ban {DefaultKeys.Player.Id} \"{PlaceholderKeys.PlayerMessage}\"", $"dsl.erase {PlaceholderKeys.EntityId} {PlaceholderKeys.TextureIndex}"
                    }
                    , PlayerMessage = string.Empty, ServerMessage = string.Empty, RequirePermissions = true, ConfirmModal = true, AllowedRoles = new List<Snowflake>(), AllowedGroups = new List<string>()
                }
            }
            ;
            for (int index = 0; index < config.Buttons.Count; index++) {
                config.Buttons[index] = new ImageButton(config.Buttons[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 (SignArtist is {
                IsLoaded : true
            }
            ) {
                if (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");
                }
            }
            else {
                Unsubscribe(nameof(OnPlayerCommand));
            }
            Client.Connect(new BotConnection {
                Intents = GatewayIntents.Guilds, ApiToken = _pluginConfig.DiscordApiKey, LogLevel = _pluginConfig.ExtensionDebugging
            }
            );
        }
        private void Unload() {
            SaveData();
            Instance = null;
        }
#endregion
#region Plugins\DiscordSignLogger.CoreHooks.cs
        private void OnImagePost(BasePlayer player, string url, bool raw, ISignage signage, uint textureIndex) {
            bool ignore = player == null || !_pluginConfig.PluginSettings.SignArtist.ShouldLog(url);
            _updates[signage.NetworkID] = new SignageUpdate(player, signage, (byte)textureIndex, ignore, 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, (byte)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) {
                PaintedItemUpdate update = new(player, entity, item, image, false);
                SendDiscordMessage(update);
            }
        }
        private void OnFireworkDesignChanged(PatternFirework firework, ProtoBuf.PatternFirework.Design design, BasePlayer player) {
            if (design?.stars != null && design.stars.Count != 0) {
                SendDiscordMessage(new FireworkUpdate(player, firework));
            }
        }
        private void OnCopyInfoToSign(SignContent content, ISignage sign, IUGCBrowserEntity browser) {
            BaseEntity entity = (BaseEntity)sign;
            BasePlayer player = BasePlayer.FindByID(entity.OwnerID);
            SignageUpdate update = new(player, sign, 0);
            SendDiscordMessage(update);
        }
        private object CanUpdateSign(BasePlayer player, BaseEntity entity) {
            if (!_pluginData.IsSignBanned(player)) {
                return null;
            }
            PlaceholderData data = GetPlaceholderData();
            data.AddTimeSpan(_pluginData.GetRemainingBan(player));
            Chat(player, LangKeys.BlockedMessage, data);
            //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;
            }
            PlaceholderData data = GetPlaceholderData();
            data.AddTimeSpan(_pluginData.GetRemainingBan(player));
            Chat(player, LangKeys.BlockedMessage, data);
            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;
            }
            PlaceholderData data = GetPlaceholderData();
            data.AddTimeSpan(_pluginData.GetRemainingBan(player));
            Chat(player, LangKeys.BlockedMessage, data);
            return _true;
        }
        private void UnsubscribeAll() {
            Unsubscribe(nameof(OnImagePost));
            Unsubscribe(nameof(OnSignUpdated));
            Unsubscribe(nameof(OnFireworkDesignChanged));
            Unsubscribe(nameof(CanUpdateSign));
            Unsubscribe(nameof(OnFireworkDesignChange));
            Unsubscribe(nameof(OnPlayerCommand));
            Unsubscribe(nameof(OnCopyInfoToSign));
        }
        private void SubscribeAll() {
            Subscribe(nameof(OnSignUpdated));
            Subscribe(nameof(OnFireworkDesignChanged));
            Subscribe(nameof(CanUpdateSign));
            Subscribe(nameof(OnFireworkDesignChange));
            Subscribe(nameof(OnCopyInfoToSign));
            if (SignArtist is {
                IsLoaded : true
            }
            ) {
                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 = guild.GetChannel(message.ChannelId);
                    if (channel != null) {
                        message.MessageChannel = channel;
                        subscribe = true;
                    }
                }
            }
            if (_pluginConfig.ActionLogChannel.IsValid()) {
                DiscordChannel channel = guild.GetChannel(_pluginConfig.ActionLogChannel);
                if (channel != null) {
                    _actionChannel = channel;
                }
            }
            if (subscribe) {
                SubscribeAll();
                Puts($"{Title} Ready");
                RegisterApplicationCommands();
            }
        }
#endregion
#region Plugins\DiscordSignLogger.DiscordHelpers.cs
        public void RunCommand(DiscordInteraction interaction, SignUpdateState state, ImageButton button, string playerMessage, string serverMessage) {
            using PlaceholderData data = GetPlaceholderData(state, interaction).AddGuild(Client, interaction.GuildId).Add(PlaceholderDataKeys.PlayerMessage, playerMessage).Add(PlaceholderDataKeys.ServerMessage, serverMessage);
            data.ManualPool();
            _sb.Clear();
            foreach (string buttonCommand in button.Commands) {
                string command = _placeholders.ProcessPlaceholders(buttonCommand, data);
                covalence.Server.Command(command);
                if (_actionChannel != null) {
                    _sb.AppendLine(command);
                }
            }
            if (_actionChannel != null) {
                string command = _sb.ToString();
                data.Add(PlaceholderDataKeys.Command, command);
                _actionChannel.CreateGlobalTemplateMessage(Client, TemplateKeys.Action.Message, null, data);
            }
            if (!string.IsNullOrEmpty(playerMessage)) {
                BasePlayer player = state.Player.Object as BasePlayer;
                if (player != null && player.IsConnected) {
                    string message = _placeholders.ProcessPlaceholders(playerMessage, data);
                    Chat(player, message);
                }
            }
            if (!string.IsNullOrEmpty(serverMessage)) {
                string message = _placeholders.ProcessPlaceholders(serverMessage, data);
                covalence.Server.Broadcast(message);
            }
            if (_pluginConfig.DisableDiscordButton) {
                DisableButton(interaction.Message, interaction.Data.CustomId);
            }
            interaction.CreateResponse(Client, new InteractionResponse {
                Type = InteractionResponseType.UpdateMessage, Data = new InteractionCallbackData {
                    Components = interaction.Message.Components
                }
            }
            );
        }
        public void ShowConfirmationModal(DiscordInteraction interaction, SignUpdateState state, ImageButton button, TemplateKey messageId, ButtonId buttonId) {
            InteractionModalBuilder builder = new(interaction);
            builder.AddModalCustomId(BuildCustomId(ModalPrefix, messageId, buttonId, state.Serialize()));
            builder.AddModalTitle(button.DisplayName);
            builder.AddInputText(PlayerMessage, "Player Message", InputTextStyles.Paragraph, button.PlayerMessage, false);
            builder.AddInputText(ServerMessage, "Server Message", InputTextStyles.Paragraph, button.ServerMessage, false);
            interaction.CreateResponse(Client, builder);
        }
        public bool UserHasButtonPermission(DiscordInteraction interaction, ImageButton 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;
            if (player != null) {
                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 bool TryParseCommand(string command, out TemplateKey messageId, out ButtonId buttonId, out SignUpdateState state) {
            messageId = default;
            buttonId = default;
            state = null;
            ReadOnlySpan<char> span = command.AsSpan();
            ReadOnlySpan<char> token = " ";
            //Command Prefix can be ignored
            if (!span.TryParseNextString(token, out span, out ReadOnlySpan<char> _)) return false;
            if (!span.TryParseNextString(token, out span, out ReadOnlySpan<char> messageIdString)) return false;
            if (!span.TryParseNextString(token, out span, out ReadOnlySpan<char> buttonIdString)) return false;
            if (!span.TryParseNextString(token, out span, out ReadOnlySpan<char> stateString)) return false;
            messageId = new TemplateKey(messageIdString.ToString());
            buttonId = new ButtonId(buttonIdString.ToString());
            state = SignUpdateState.Deserialize(stateString);
            return true;
        }
        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 button && 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 button) {
                        button.Disabled = true;
                    }
                }
            }
        }
        public void SendErrorResponse(DiscordInteraction interaction, TemplateKey template, PlaceholderData data) {
            DisableAllButtons(interaction.Message);
            SendComponentUpdateResponse(interaction);
            SendFollowupResponse(interaction, template, data);
        }
        public void SendComponentUpdateResponse(DiscordInteraction interaction) {
            interaction.CreateResponse(Client, new InteractionResponse {
                Type = InteractionResponseType.UpdateMessage, Data = new InteractionCallbackData {
                    Components = interaction.Message.Components
                }
            }
            );
        }
        public void SendTemplateResponse(DiscordInteraction interaction, TemplateKey templateName, PlaceholderData data) {
            interaction.CreateTemplateResponse(Client, InteractionResponseType.ChannelMessageWithSource, templateName, null, data);
        }
        public void SendFollowupResponse(DiscordInteraction interaction, TemplateKey templateName, PlaceholderData data) {
            interaction.CreateFollowUpTemplateResponse(Client, templateName, null, data);
        }
        public IEnumerable<IPlayer> GetBannedPlayers() {
            foreach (ulong key in _pluginData.SignBannedUsers.Keys) {
                IPlayer player = FindPlayerById(StringCache<ulong>.Instance.ToString(key));
                if (player != null) {
                    yield return player;
                }
            }
        }
#endregion
#region Plugins\DiscordSignLogger.DiscordMethods.cs
        public void SendDiscordMessage(BaseImageUpdate update) {
            SignUpdateState state = new(update);
            StateKey encodedState = state.Serialize();
            using PlaceholderData data = GetPlaceholderData(state);
            data.ManualPool();
            data.AddPlayer(state.Player).Add(PlaceholderDataKeys.State, state).Add(PlaceholderDataKeys.Owner, state.Owner).Add(PlaceholderDataKeys.MessageState, encodedState);
            if (update is SignageUpdate signage) {
                data.Add(PlaceholderDataKeys.SignArtistUrl, signage.Url);
            }
            for (int index = 0; index < _pluginConfig.SignMessages.Count; index++) {
                SignMessage signMessage = _pluginConfig.SignMessages[index];
                DiscordMessageTemplate message = _templates.GetGlobalTemplate(this, signMessage.MessageId);
                MessageCreate create = message.ToMessage<MessageCreate>(data);
                data.Add(PlaceholderDataKeys.MessageId, signMessage.MessageId);
                create.AddAttachment("image.png", update.GetImage(), "image/png", $"{update.DisplayName} Updated {update.Entity.ShortPrefabName} @{update.Entity.transform.position} On {DateTime.Now:f}");
                if (signMessage.Buttons.Count != 0) {
                    if (signMessage.UseActionButton) {
                        create.Components = new List<ActionRowComponent> {
                            new() {
                                Components = {
                                    _buttonTemplates.GetGlobalTemplate(this, TemplateKeys.Action.Button).ToComponent(data)
                                }
                            }
                        }
                        ;
                    }
                    else {
                        create.Components = CreateButtons(signMessage, data, encodedState);
                    }
                }
                signMessage.MessageChannel?.CreateMessage(Client, create);
            }
        }
        private List<ActionRowComponent> CreateButtons(SignMessage signMessage, PlaceholderData data, StateKey encodedState) {
            MessageComponentBuilder builder = new();
            for (int i = 0; i < signMessage.Buttons.Count; i++) {
                ButtonId buttonId = signMessage.Buttons[i];
                ImageButton command = _imageButtons[buttonId];
                if (command.Commands.Count == 0) {
                    continue;
                }
                if (command.Style == ButtonStyle.Link) {
                    builder.AddLinkButton(command.DisplayName, _placeholders.ProcessPlaceholders(command.Commands[0], data));
                }
                else {
                    builder.AddActionButton(command.Style, command.DisplayName, BuildCustomId(CommandPrefix, signMessage.MessageId, buttonId, encodedState));
                }
            }
            return builder.Build();
        }
        private string BuildCustomId(string command, IDiscordKey messageId, ButtonId? buttonId, IDiscordKey encodedState) {
            return $"{command} {messageId.ToString()} {(buttonId.HasValue ? buttonId.Value.Id : "_")} {encodedState}";
        }
#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) {
                return;
            }
            switch (entity) {
                case ISignage signage : {
                    uint[] textures = signage.GetTextureCRCs();
                    uint crc = textures[index];
                    if (crc != 0) {
                        FileStorage.server.RemoveExact(crc, FileStorage.Type.png, signage.NetworkID, index);
                        textures[index] = 0;
                        entity.SendNetworkUpdate();
                        HandleReplaceImage(signage, index);
                    }
                    break;
                }
                case PaintedItemStorageEntity item : {
                    if (item._currentImageCrc != 0) {
                        FileStorage.server.RemoveExact(item._currentImageCrc, FileStorage.Type.png, item.net.ID, 0);
                        item._currentImageCrc = 0;
                        item.SendNetworkUpdate();
                    }
                    break;
                }
                case PatternFirework firework : firework.Design?.Dispose();
                firework.Design = null;
                firework.SendNetworkUpdateImmediate();
                break;
            }
        }
        [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);
            using PlaceholderData data = GetPlaceholderData();
            data.ManualPool();
            data.AddTimeSpan(TimeSpan.FromSeconds(duration));
            if (duration <= 0) {
                arg.ReplyWith($"{playerId} has been sign blocked permanently");
            }
            else {
                arg.ReplyWith(_placeholders.ProcessPlaceholders($"{playerId} has been sign blocked for {DefaultKeys.Timespan.Formatted}", data));
            }
            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 == EraseMode.None || SignArtist is not {
                IsLoaded : true
            }
            ) {
                return;
            }
            ReplaceImageSettings image = _pluginConfig.ReplaceImage;
            if (signage is Signage) {
                if (image.Mode == EraseMode.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 IPlayer FindPlayerById(string id) => covalence.Players.FindPlayerById(id);
        public void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, _pluginData);
        public void Puts(string format) => base.Puts(format);
#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 {DefaultKeys.Timespan.Formatted}.",
            }
            , 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] = $"Возможность использовать изображения на знаке/феерверке для вас заблокирована.Разблокировка через {DefaultKeys.Timespan.Formatted}.",
            }
            , this, "ru");
        }
        public string Lang(string key, BasePlayer player = null) {
            return lang.GetMessage(key, this, player ? player.UserIDString : null);
        }
        public string Lang(string key, BasePlayer player, PlaceholderData data) {
            return _placeholders.ProcessPlaceholders(Lang(key, player), data);
        }
        public string Lang(string key, BasePlayer player = null, params object[] args) {
            try {
                return string.Format(Lang(key, player), 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, PlaceholderData data) => PrintToChat(player, Lang(LangKeys.Chat, player, Lang(key, player, data)));
#endregion
#region Plugins\DiscordSignLogger.Placeholders.cs
        public void RegisterPlaceholders() {
            _placeholders.RegisterPlaceholder<SignUpdateState, ulong>(this, PlaceholderKeys.EntityId, PlaceholderDataKeys.State, state => state.EntityId);
            _placeholders.RegisterPlaceholder<SignUpdateState, string>(this, PlaceholderKeys.EntityName, PlaceholderDataKeys.State, state => GetEntityName(state.Entity));
            _placeholders.RegisterPlaceholder<SignUpdateState, string>(this, PlaceholderKeys.ItemName, PlaceholderDataKeys.State, state => GetItemName(state.ItemId));
            _placeholders.RegisterPlaceholder<string>(this, PlaceholderKeys.PlayerMessage, PlaceholderDataKeys.PlayerMessage);
            _placeholders.RegisterPlaceholder<string>(this, PlaceholderKeys.ServerMessage, PlaceholderDataKeys.ServerMessage);
            _placeholders.RegisterPlaceholder<string>(this, PlaceholderKeys.SignArtistUrl, PlaceholderDataKeys.SignArtistUrl);
            _placeholders.RegisterPlaceholder<string>(this, PlaceholderKeys.Command, PlaceholderDataKeys.Command);
            _placeholders.RegisterPlaceholder<string>(this, PlaceholderKeys.ButtonId, PlaceholderDataKeys.ButtonId);
            _placeholders.RegisterPlaceholder<string>(this, PlaceholderKeys.PlayerId, PlaceholderDataKeys.PlayerId);
            _placeholders.RegisterPlaceholder<SignUpdateState, bool>(this, PlaceholderKeys.IsOutside, PlaceholderDataKeys.State, state => state.Entity && state.Entity.IsOutside());
            _placeholders.RegisterPlaceholder<TemplateKey>(this, PlaceholderKeys.MessageId, PlaceholderDataKeys.MessageId);
            _placeholders.RegisterPlaceholder<StateKey, string>(this, PlaceholderKeys.MessageState, PlaceholderDataKeys.MessageState, state => state.State);
            _placeholders.RegisterPlaceholder<SignUpdateState, string>(this, PlaceholderKeys.TextureIndex, PlaceholderDataKeys.State, state => {
                if (state.Entity is ISignage signage && signage.GetTextureCRCs().Length <= 1) {
                    return null;
                }
                return StringCache<byte>.Instance.ToString(state.TextureIndex);
            }
            );
            _placeholders.RegisterPlaceholder<SignUpdateState, GenericPosition>(this, PlaceholderKeys.Position, PlaceholderDataKeys.State, state => {
                BaseEntity entity = state.Entity;
                Vector3 pos = entity ? entity.transform.position : Vector3.zero;
                return new GenericPosition(pos.x, pos.y, pos.z);
            }
            );
            PlayerPlaceholders.RegisterPlaceholders(this, PlaceholderKeys.OwnerKeys, PlaceholderDataKeys.Owner);
        }
        public PlaceholderData GetPlaceholderData(SignUpdateState state, DiscordInteraction interaction) => GetPlaceholderData(state).AddInteraction(interaction);
        public PlaceholderData GetPlaceholderData(SignUpdateState state) {
            return GetPlaceholderData().AddPlayer(state.Player).Add(PlaceholderDataKeys.State, state).Add(PlaceholderDataKeys.Owner, state.Owner);
        }
        public PlaceholderData GetPlaceholderData(DiscordInteraction interaction) => GetPlaceholderData().AddInteraction(interaction);
        public PlaceholderData GetPlaceholderData() {
            return _placeholders.CreateData(this);
        }
#endregion
#region Plugins\DiscordSignLogger.Templates.cs
        public void RegisterTemplates() {
            HashSet<string> messages = new();
            foreach (SignMessage message in _pluginConfig.SignMessages) {
                if (messages.Add(message.MessageId.Name)) {
                    _templates.RegisterGlobalTemplateAsync(this, message.MessageId, CreateDefaultTemplate(), new TemplateVersion(1, 0, 2), new TemplateVersion(1, 0, 2));
                }
                else {
                    PrintWarning($"Duplicate Message ID: '{message.MessageId.Name}'.Please check your config and correct the duplicate Sign Message ID's");
                }
            }
            _templates.RegisterGlobalTemplateAsync(this, TemplateKeys.Action.Message, CreateActionMessage($"{DefaultKeys.User.Mention} ran command \"{PlaceholderKeys.Command}\"", DiscordColor.Blurple), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _buttonTemplates.RegisterGlobalTemplateAsync(this, TemplateKeys.Action.Button, new ButtonTemplate("Actions", ButtonStyle.Primary, BuildCustomId(ActionPrefix, PlaceholderKeys.MessageId, null, PlaceholderKeys.MessageState)), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            RegisterEn();
            RegisterRu();
        }
        public void RegisterEn() {
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.NoPermission, CreateMessage("You do not have permission to perform this action", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Errors.FailedToParse, CreateMessage("An error occurred parsing button data", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Errors.ButtonIdNotFound, CreateMessage($"Failed to find button with id: {PlaceholderKeys.ButtonId}.Please validate the button exists in the config.", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Commands.Block.Success, CreateMessage($"{DefaultKeys.Player.Name} ({DefaultKeys.Player.Id}) has been sign blocked for {DefaultKeys.Timespan.Formatted}.", DiscordColor.Success), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Commands.Block.Errors.PlayerNotFound, CreateMessage($"Failed to find player with id: {PlaceholderKeys.PlayerId}", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Commands.Block.Errors.IsAlreadyBanned, CreateMessage($"{DefaultKeys.Player.Name} ({DefaultKeys.Player.Id}) is already banned", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Commands.Unblock.Success, CreateMessage($"You have removed {DefaultKeys.Player.Name} ({DefaultKeys.Player.Id}) sign block.", DiscordColor.Success), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Commands.Unblock.Errors.PlayerNotFound, CreateMessage($"Failed to find player with id: {PlaceholderKeys.PlayerId}", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Commands.Unblock.Errors.NotBanned, CreateMessage($"{DefaultKeys.Player.Name} ({DefaultKeys.Player.Id}) is not sign blocked.", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0));
        }
        public void RegisterRu() {
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.NoPermission, CreateMessage("У вас нет разрешения на выполнение этого действия", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0), "ru");
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Errors.FailedToParse, CreateMessage("Произошла ошибка при анализе данных кнопки.", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0), "ru");
            _templates.RegisterLocalizedTemplateAsync(this, TemplateKeys.Errors.ButtonIdNotFound, CreateMessage($"Не удалось найти кнопку с идентификатором: {PlaceholderKeys.ButtonId}.Пожалуйста, проверьте наличие кнопки в файле конфигурации.", DiscordColor.Danger), new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0), "ru");
        }
        public DiscordMessageTemplate CreateMessage(string description, DiscordColor color) {
            return new DiscordMessageTemplate {
                Embeds = new List<DiscordEmbedTemplate> {
                    CreateEmbedTemplate(description, color)
                }
            }
            ;
        }
        public DiscordMessageTemplate CreateActionMessage(string description, DiscordColor color) {
            return new DiscordMessageTemplate {
                Embeds = new List<DiscordEmbedTemplate> {
                    CreateEmbedTemplate(description, color)
                }
                , Components = new List<BaseComponentTemplate> {
                    new ButtonTemplate("Image Message", ButtonStyle.Link, "discord://-/channels/{guild.id}/{channel.id}/{message.id}")
                }
            }
            ;
        }
        public DiscordEmbedTemplate CreateEmbedTemplate(string description, DiscordColor color) {
            return new() {
                Description = $"[{Title}] {description}", Color = color.ToHex(), Footer = GetFooterTemplate()
            }
            ;
        }
        public DiscordMessageTemplate CreateDefaultTemplate() {
            return new DiscordMessageTemplate {
                Embeds = new List<DiscordEmbedTemplate> {
                    new() {
                        Title = $"{DefaultKeys.Server.Name}", Color = "#AC7061", ImageUrl = "attachment://image.png", TimeStamp = true, Fields = new List<DiscordEmbedFieldTemplate> {
                            new() {
                                Name = "Player:", Value = $"{DefaultKeys.Player.Name} ([{DefaultKeys.Player.Id}]({DefaultKeys.Player.SteamProfile}))", Inline = true
                            }
                            , new() {
                                Name = "Owner:", Value = $"{PlaceholderKeys.OwnerKeys.Name} ([{PlaceholderKeys.OwnerKeys.Id}]({PlaceholderKeys.OwnerKeys.SteamProfile}))", Inline = true
                            }
                            , new() {
                                Name = "Position:", Value = $"{PlaceholderKeys.Position}", Inline = true
                            }
                            , new() {
                                Name = "Item:", Value = $"{PlaceholderKeys.EntityName}", Inline = true
                            }
                            , new() {
                                Name = "Is Outside:", Value = $"{PlaceholderKeys.IsOutside}", Inline = true
                            }
                            , new() {
                                Name = "Texture Index", Value = $"{PlaceholderKeys.TextureIndex}", Inline = true, HideIfEmpty = true
                            }
                            , new() {
                                Name = "Sign Artist URL", Value = $"{PlaceholderKeys.SignArtistUrl}", Inline = true, HideIfEmpty = true
                            }
                        }
                        , Footer = GetFooterTemplate()
                    }
                }
            }
            ;
        }
        public EmbedFooterTemplate GetFooterTemplate() {
            return new EmbedFooterTemplate {
                Enabled = true, Text = $"{DefaultKeys.Plugin.Name} V{DefaultKeys.Plugin.Version} by {DefaultKeys.Plugin.Author}", IconUrl = "https://assets.umod.org/images/icons/plugin/61f1b7f6da7b6.png"
            }
            ;
        }
#endregion
#region Plugins\DiscordSignLogger.RustTranslationApi.cs
        public string GetEntityName(BaseEntity entity) {
            if (!entity.IsValid()) {
                return string.Empty;
            }
            if (_prefabNameCache.TryGetValue(entity.prefabID, out string name)) {
                return name;
            }
            if (RustTranslationAPI is {
                IsLoaded : true
            }
            ) {
                name = RustTranslationAPI.Call<string>("GetDeployableTranslation", lang.GetServerLanguage(), entity.ShortPrefabName);
                if (!string.IsNullOrEmpty(name)) {
                    _prefabNameCache[entity.prefabID] = name;
                    return name;
                }
            }
            _prefabNameCache[entity.prefabID] = entity.ShortPrefabName;
            return entity.ShortPrefabName;
        }
        public string GetItemName(int itemId) {
            if (itemId == 0) {
                return string.Empty;
            }
            if (_itemNameCache.TryGetValue(itemId, out string name)) {
                return name;
            }
            if (RustTranslationAPI is {
                IsLoaded : true
            }
            ) {
                name = RustTranslationAPI.Call<string>("GetItemTranslationByID", lang.GetServerLanguage(), itemId);
                if (!string.IsNullOrEmpty(name)) {
                    _itemNameCache[itemId] = name;
                    return name;
                }
            }
            name = ItemManager.FindItemDefinition(itemId).displayName.translated;
            _itemNameCache[itemId] = name;
            return name;
        }
#endregion
#region Plugins\DiscordSignLogger.AppCommands.cs
        public void RegisterApplicationCommands() {
            ApplicationCommandBuilder builder = new ApplicationCommandBuilder(AppCommand.Command, "Discord Sign Logger Commands", ApplicationCommandType.ChatInput).AddDefaultPermissions(PermissionFlags.None);
            AddBlockCommand(builder);
            AddUnblockCommand(builder);
            CommandCreate build = builder.Build();
            DiscordCommandLocalization localization = builder.BuildCommandLocalization();
            TemplateKey template = new("Command");
            _local.RegisterCommandLocalizationAsync(this, template, localization, new TemplateVersion(1, 0, 0), new TemplateVersion(1, 0, 0)).Then(_ => {
                _local.ApplyCommandLocalizationsAsync(this, build, template).Then(() => {
          
// ... [Code preview truncated due to length. Full source in attached file] ...

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