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

FREE DiscordLogger : 2.0.20 2.0.20

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Net;
using System.Text.RegularExpressions;
using System.Text;

using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Discord Logger", "MON@H", "2.0.20")]
    [Description("Logs events to Discord channels using webhooks")]
    public class DiscordLogger : RustPlugin
    {
        #region Variables

        [PluginReference] private readonly Plugin AntiSpam, BetterChatMute, CallHeli, PersonalHeli, UFilter;

        private readonly Hash<ulong, CargoShip> _cargoShips = new();
        private readonly List<ulong> _listBadCargoShips = new();
        private readonly List<ulong> _listSupplyDrops = new();
        private readonly Queue<QueuedMessage> _queue = new();
        private readonly StringBuilder _sb = new();

        private EventSettings _eventSettings;
        private int _retryCount = 0;
        private object _resultCall;
        private QueuedMessage _nextMessage;
        private QueuedMessage _queuedMessage;
        private string _langKey;
        private string[] _profanities;
        private Timer _timerQueue;
        private Timer _timerQueueCooldown;
        private ulong _entityID;
        private Vector3 _locationLargeOilRig;
        private Vector3 _locationOilRig;

        private readonly List<Regex> _regexTags = new()

        {
            new("<color=.+?>", RegexOptions.Compiled),
            new("<size=.+?>", RegexOptions.Compiled)
        };

        private readonly List<string> _tags = new()

        {
            "</color>",
            "</size>",
            "<i>",
            "</i>",
            "<b>",
            "</b>"
        };

        private class QueuedMessage
        {
            public string WebhookUrl {set; get;}
            public string Message {set; get;}
        }

        public enum TeamEventType
        {
            Created,
            Disbanded,
            Updated,
        }

        private class Response {
            [JsonProperty("country")]
            public string Country { get; set; }

            [JsonProperty("countryCode")]
            public string CountryCode { get; set; }
        }

        #endregion Variables

        #region Initialization

        private void Init()
        {
            UnsubscribeHooks();
        }

        private void Unload()
        {
            Application.logMessageReceivedThreaded -= HandleLog;
        }

        private void OnServerInitialized(bool isStartup)
        {
            if (isStartup && _configData.ServerStateSettings.Enabled)
            {
                LogToConsole("Server is online again!");

                DiscordSendMessage(Lang(LangKeys.Event.Initialized), _configData.ServerStateSettings.WebhookURL);
            }

            CacheOilRigsLocation();
            SubscribeHooks();
        }

        private void OnServerShutdown()
        {
            if (_configData.ServerStateSettings.Enabled)
            {
                LogToConsole("Server is shutting down!");

                string url = GetWebhookURL(_configData.ServerStateSettings.WebhookURL);

                if (!string.IsNullOrEmpty(url))
                {
                    webrequest.Enqueue(url, new DiscordMessage(Lang(LangKeys.Event.Shutdown)).ToJson(), DiscordSendMessageCallback, null, RequestMethod.POST, _headers);
                }
            }
        }

        #endregion Initialization

        #region Configuration

        private ConfigData _configData;

        private class ConfigData
        {
            [JsonProperty(PropertyName = "Global settings")]
            public GlobalSettings GlobalSettings = new();

            [JsonProperty(PropertyName = "Admin Hammer settings")]
            public EventSettings AdminHammerSettings = new();

            [JsonProperty(PropertyName = "Admin Radar settings")]
            public EventSettings AdminRadarSettings = new();

            [JsonProperty(PropertyName = "Bradley settings")]
            public EventSettings BradleySettings = new();

            [JsonProperty(PropertyName = "Cargo Ship settings")]
            public EventSettings CargoShipSettings = new();

            [JsonProperty(PropertyName = "Cargo Plane settings")]
            public EventSettings CargoPlaneSettings = new();

            [JsonProperty(PropertyName = "Chat settings")]
            public EventSettings ChatSettings = new();

            [JsonProperty(PropertyName = "Chat (Team) settings")]
            public EventSettings ChatTeamSettings = new();

            [JsonProperty(PropertyName = "CH47 Helicopter settings")]
            public EventSettings ChinookSettings = new();

            [JsonProperty(PropertyName = "Christmas settings")]
            public EventSettings ChristmasSettings = new();

            [JsonProperty(PropertyName = "Clan settings")]
            public EventSettings ClanSettings = new();

            [JsonProperty(PropertyName = "Dangerous Treasures settings")]
            public EventSettings DangerousTreasuresSettings = new();

            [JsonProperty(PropertyName = "Duel settings")]
            public EventSettings DuelSettings = new();

            [JsonProperty(PropertyName = "Godmode settings")]
            public EventSettings GodmodeSettings = new();

            [JsonProperty(PropertyName = "Easter settings")]
            public EventSettings EasterSettings = new();

            [JsonProperty(PropertyName = "Error settings")]
            public EventSettings ErrorSettings = new();

            [JsonProperty(PropertyName = "Hackable Locked Crate settings")]
            public EventSettings LockedCrateSettings = new();

            [JsonProperty(PropertyName = "Halloween settings")]
            public EventSettings HalloweenSettings = new();

            [JsonProperty(PropertyName = "Helicopter settings")]
            public EventSettings HelicopterSettings = new();

            [JsonProperty(PropertyName = "NTeleportation settings")]
            public EventSettings NTeleportationSettings = new();

            [JsonProperty(PropertyName = "Permissions settings")]
            public EventSettings PermissionsSettings = new();

            [JsonProperty(PropertyName = "Player death settings")]
            public EventSettings PlayerDeathSettings = new();

            [JsonProperty(PropertyName = "Player DeathNotes settings")]
            public EventSettings PlayerDeathNotesSettings = new();

            [JsonProperty(PropertyName = "Player connect advanced info settings")]
            public EventSettings PlayerConnectedInfoSettings = new();

            [JsonProperty(PropertyName = "Player connect settings")]
            public EventSettings PlayerConnectedSettings = new();

            [JsonProperty(PropertyName = "Player disconnect settings")]
            public EventSettings PlayerDisconnectedSettings = new();

            [JsonProperty(PropertyName = "Player Respawned settings")]
            public EventSettings PlayerRespawnedSettings = new();

            [JsonProperty(PropertyName = "Private Messages settings")]
            public EventSettings PrivateMessagesSettings = new();

            [JsonProperty(PropertyName = "Raidable Bases settings")]
            public EventSettings RaidableBasesSettings = new();

            [JsonProperty(PropertyName = "Rcon command settings")]
            public EventSettings RconCommandSettings = new();

            [JsonProperty(PropertyName = "Rcon connection settings")]
            public EventSettings RconConnectionSettings = new();

            [JsonProperty(PropertyName = "Rust Kits settings")]
            public EventSettings RustKitsSettings = new();

            [JsonProperty(PropertyName = "SantaSleigh settings")]
            public EventSettings SantaSleighSettings = new();

            [JsonProperty(PropertyName = "Server messages settings")]
            public EventSettings ServerMessagesSettings = new();

            [JsonProperty(PropertyName = "Server state settings")]
            public EventSettings ServerStateSettings = new();

            [JsonProperty(PropertyName = "Supply Drop settings")]
            public EventSettings SupplyDropSettings = new();

            [JsonProperty(PropertyName = "Teams settings")]
            public EventSettings TeamsSettings = new();

            [JsonProperty(PropertyName = "User Banned settings")]
            public EventSettings UserBannedSettings = new();

            [JsonProperty(PropertyName = "User Kicked settings")]
            public EventSettings UserKickedSettings = new();

            [JsonProperty(PropertyName = "User Muted settings")]
            public EventSettings UserMutedSettings = new();

            [JsonProperty(PropertyName = "User Name Updated settings")]
            public EventSettings UserNameUpdateSettings = new();

            [JsonProperty(PropertyName = "Vanish settings")]
            public EventSettings VanishSettings = new();
        }

        private class GlobalSettings
        {
            [JsonProperty(PropertyName = "Log to console?")]
            public bool LoggingEnabled = false;

            [JsonProperty(PropertyName = "Use AntiSpam plugin on chat messages")]
            public bool UseAntiSpam = false;

            [JsonProperty(PropertyName = "Use UFilter plugin on chat messages")]
            public bool UseUFilter = false;

            [JsonProperty(PropertyName = "Hide admin connect/disconnect messages")]
            public bool HideAdmin = false;

            [JsonProperty(PropertyName = "Hide NPC death messages")]
            public bool HideNPC = false;

            [JsonProperty(PropertyName = "Replacement string for tags")]
            public string TagsReplacement = "`";

            [JsonProperty(PropertyName = "Queue interval (1 message per ? seconds)")]
            public float QueueInterval = 1f;

            [JsonProperty(PropertyName = "Queue cooldown if connection error (seconds)")]
            public float QueueCooldown = 60f;

            [JsonProperty(PropertyName = "Default WebhookURL")]
            public string DefaultWebhookURL = string.Empty;

            [JsonProperty(PropertyName = "RCON command blacklist", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> RCONCommandBlacklist = new()
            {
                "playerlist",
                "status"
            };
        }

        private class EventSettings
        {
            [JsonProperty(PropertyName = "WebhookURL")]
            public string WebhookURL = "";

            [JsonProperty(PropertyName = "Enabled?")]
            public bool Enabled = false;
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _configData = Config.ReadObject<ConfigData>();
                if (_configData == null)
                {
                    LoadDefaultConfig();
                    SaveConfig();
                }
            }
            catch
            {
                PrintError("The configuration file is corrupted");
                LoadDefaultConfig();
                SaveConfig();
            }
        }

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Creating a new configuration file");
            _configData = new();
        }

        protected override void SaveConfig() => Config.WriteObject(_configData);

        #endregion Configuration

        #region Localization

        public string Lang(string key, string userIDString = null, params object[] args)
        {
            try
            {
                return string.Format(lang.GetMessage(key, this, userIDString).Replace("{time}", $"<t:{DateTimeOffset.Now.ToUnixTimeSeconds()}:t>"), args);
            }
            catch (Exception ex)
            {
                PrintError($"Lang Key '{key}' threw exception:\n{ex}");
                throw;
            }
        }

        private static class LangKeys
        {
            public static class Event
            {
                private const string Base = nameof(Event) + ".";
                public const string Bradley = Base + nameof(Bradley);
                public const string CargoPlane = Base + nameof(CargoPlane);
                public const string CargoShip = Base + nameof(CargoShip);
                public const string Chat = Base + nameof(Chat);
                public const string ChatTeam = Base + nameof(ChatTeam);
                public const string Chinook = Base + nameof(Chinook);
                public const string Christmas = Base + nameof(Christmas);
                public const string Death = Base + nameof(Death);
                public const string Easter = Base + nameof(Easter);
                public const string EasterWinner = Base + nameof(EasterWinner);
                public const string Error = Base + nameof(Error);
                public const string Halloween = Base + nameof(Halloween);
                public const string HalloweenWinner = Base + nameof(HalloweenWinner);
                public const string Helicopter = Base + nameof(Helicopter);
                public const string Initialized = Base + nameof(Initialized);
                public const string LockedCrate = Base + nameof(LockedCrate);
                public const string PlayerConnected = Base + nameof(PlayerConnected);
                public const string PlayerConnectedInfo = Base + nameof(PlayerConnectedInfo);
                public const string PlayerDisconnected = Base + nameof(PlayerDisconnected);
                public const string PlayerRespawned = Base + nameof(PlayerRespawned);
                public const string RconCommand = Base + nameof(RconCommand);
                public const string RconConnection = Base + nameof(RconConnection);
                public const string SantaSleigh = Base + nameof(SantaSleigh);
                public const string ServerMessage = Base + nameof(ServerMessage);
                public const string Shutdown = Base + nameof(Shutdown);
                public const string SupplyDrop = Base + nameof(SupplyDrop);
                public const string SupplyDropLanded = Base + nameof(SupplyDropLanded);
                public const string SupplySignal = Base + nameof(SupplySignal);
                public const string Team = Base + nameof(Team);
                public const string UserBanned = Base + nameof(UserBanned);
                public const string UserKicked = Base + nameof(UserKicked);
                public const string UserMuted = Base + nameof(UserMuted);
                public const string UserNameUpdated = Base + nameof(UserNameUpdated);
                public const string UserUnbanned = Base + nameof(UserUnbanned);
                public const string UserUnmuted = Base + nameof(UserUnmuted);
            }

            public static class Permission
            {
                private const string Base = nameof(Permission) + ".";
                public const string GroupCreated = Base + nameof(GroupCreated);
                public const string GroupDeleted = Base + nameof(GroupDeleted);
                public const string UserGroupAdded = Base + nameof(UserGroupAdded);
                public const string UserGroupRemoved = Base + nameof(UserGroupRemoved);
                public const string UserPermissionGranted = Base + nameof(UserPermissionGranted);
                public const string UserPermissionRevoked = Base + nameof(UserPermissionRevoked);
            }

            public static class Plugin
            {
                private const string Base = nameof(Plugin) + ".";
                public const string AdminHammerOff = Base + nameof(AdminHammerOff);
                public const string AdminHammerOn = Base + nameof(AdminHammerOn);
                public const string AdminRadarOff = Base + nameof(AdminRadarOff);
                public const string AdminRadarOn = Base + nameof(AdminRadarOn);
                public const string ClanCreated = Base + nameof(ClanCreated);
                public const string ClanDisbanded = Base + nameof(ClanDisbanded);
                public const string DangerousTreasuresEnded = Base + nameof(DangerousTreasuresEnded);
                public const string DangerousTreasuresStarted = Base + nameof(DangerousTreasuresStarted);
                public const string DeathNotes = Base + nameof(DeathNotes);
                public const string Duel = Base + nameof(Duel);
                public const string GodmodeOff = Base + nameof(GodmodeOff);
                public const string GodmodeOn = Base + nameof(GodmodeOn);
                public const string NTeleportation = Base + nameof(NTeleportation);
                public const string PersonalHelicopter = Base + nameof(PersonalHelicopter);
                public const string PrivateMessage = Base + nameof(PrivateMessage);
                public const string RaidableBaseCompleted = Base + nameof(RaidableBaseCompleted);
                public const string RaidableBaseEnded = Base + nameof(RaidableBaseEnded);
                public const string RaidableBaseStarted = Base + nameof(RaidableBaseStarted);
                public const string RustKits = Base + nameof(RustKits);
                public const string TimedGroupAdded = Base + nameof(TimedGroupAdded);
                public const string TimedGroupExtended = Base + nameof(TimedGroupExtended);
                public const string TimedPermissionExtended = Base + nameof(TimedPermissionExtended);
                public const string TimedPermissionGranted = Base + nameof(TimedPermissionGranted);
                public const string VanishOff = Base + nameof(VanishOff);
                public const string VanishOn = Base + nameof(VanishOn);
            }

            public static class Format
            {
                private const string Base = nameof(Format) + ".";
                public const string CargoShip = Base + nameof(CargoShip);
                public const string Created = Base + nameof(Created);
                public const string Day = Base + nameof(Day);
                public const string Days = Base + nameof(Days);
                public const string Disbanded = Base + nameof(Disbanded);
                public const string Easy = Base + nameof(Easy);
                public const string Expert = Base + nameof(Expert);
                public const string Hard = Base + nameof(Hard);
                public const string Hour = Base + nameof(Hour);
                public const string Hours = Base + nameof(Hours);
                public const string LargeOilRig = Base + nameof(LargeOilRig);
                public const string Medium = Base + nameof(Medium);
                public const string Minute = Base + nameof(Minute);
                public const string Minutes = Base + nameof(Minutes);
                public const string Nightmare = Base + nameof(Nightmare);
                public const string OilRig = Base + nameof(OilRig);
                public const string Second = Base + nameof(Second);
                public const string Seconds = Base + nameof(Seconds);
                public const string Updated = Base + nameof(Updated);
            }
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new()
            {
                [LangKeys.Event.Bradley] = ":dagger: {time} Bradley spawned `{0}`",
                [LangKeys.Event.CargoPlane] = ":airplane: {time} Cargo Plane incoming `{0}`",
                [LangKeys.Event.CargoShip] = ":ship: {time} Cargo Ship incoming `{0}`",
                [LangKeys.Event.Chat] = ":speech_left: {time} **{0}**: {1}",
                [LangKeys.Event.ChatTeam] = ":busts_in_silhouette: {time} **{0}**: {1}",
                [LangKeys.Event.Chinook] = ":helicopter: {time} Chinook 47 incoming `{0}`",
                [LangKeys.Event.Christmas] = ":christmas_tree: {time} Christmas event started",
                [LangKeys.Event.Death] = ":skull: {time} `{0}` died",
                [LangKeys.Event.Easter] = ":egg: {time} Easter event started",
                [LangKeys.Event.EasterWinner] = ":egg: {time} Easter event ended.The winner is `{0}`",
                [LangKeys.Event.Error] = ":octagonal_sign: {time}\n{0}",
                [LangKeys.Event.Halloween] = ":jack_o_lantern: {time} Halloween event started",
                [LangKeys.Event.HalloweenWinner] = ":jack_o_lantern: {time} Halloween event ended.The winner is `{0}`",
                [LangKeys.Event.Helicopter] = ":dagger: {time} Helicopter incoming `{0}`",
                [LangKeys.Event.Initialized] = ":ballot_box_with_check: {time} Server is online again!",
                [LangKeys.Event.LockedCrate] = ":package: {time} Codelocked crate is here `{0}`",
                [LangKeys.Event.PlayerConnected] = ":white_check_mark: {time} {0} connected",
                [LangKeys.Event.PlayerConnectedInfo] = ":detective: {time} {0} connected.SteamID: `{1}` IP: `{2}`",
                [LangKeys.Event.PlayerDisconnected] = ":x: {time} {0} disconnected ({1})",
                [LangKeys.Event.PlayerRespawned] = ":baby_symbol: {time} `{0}` has been spawned at `{1}`",
                [LangKeys.Event.RconCommand] = ":satellite: {time} RCON command `{0}` is run from `{1}`",
                [LangKeys.Event.RconConnection] = ":satellite: {time} RCON connection is opened from `{0}`",
                [LangKeys.Event.Team] = ":family_man_girl_boy: {time} Team was `{0}`\n{1}",
                [LangKeys.Event.SantaSleigh] = ":santa: {time} SantaSleigh Event started",
                [LangKeys.Event.ServerMessage] = ":desktop: {time} `{0}`",
                [LangKeys.Event.Shutdown] = ":stop_sign: {time} Server is shutting down!",
                [LangKeys.Event.SupplyDrop] = ":parachute: {time} SupplyDrop incoming at `{0}`",
                [LangKeys.Event.SupplyDropLanded] = ":gift: {time} SupplyDrop landed at `{0}`",
                [LangKeys.Event.SupplySignal] = ":firecracker: {time} SupplySignal was thrown by `{0}` at `{1}`",
                [LangKeys.Event.UserBanned] = ":no_entry: {time} Player `{0}` SteamID: `{1}` IP: `{2}` was banned: `{3}`",
                [LangKeys.Event.UserKicked] = ":hiking_boot: {time} Player `{0}` SteamID: `{1}` was kicked: `{2}`",
                [LangKeys.Event.UserMuted] = ":mute: {time} `{0}` was muted by `{1}` for `{2}` (`{3}`)",
                [LangKeys.Event.UserNameUpdated] = ":label: {time} `{0}` changed name to `{1}` SteamID: `{2}`",
                [LangKeys.Event.UserUnbanned] = ":ok: {time} Player `{0}` SteamID: `{1}` IP: `{2}` was unbanned",
                [LangKeys.Event.UserUnmuted] = ":speaker: {time} `{0}` was unmuted `{1}`",
                [LangKeys.Format.CargoShip] = "Cargo Ship",
                [LangKeys.Format.Created] = "created",
                [LangKeys.Format.Day] = "day",
                [LangKeys.Format.Days] = "days",
                [LangKeys.Format.Disbanded] = "disbanded",
                [LangKeys.Format.Easy] = "Easy",
                [LangKeys.Format.Expert] = "Expert",
                [LangKeys.Format.Hard] = "Hard",
                [LangKeys.Format.Hour] = "hour",
                [LangKeys.Format.Hours] = "hours",
                [LangKeys.Format.LargeOilRig] = "Large Oil Rig",
                [LangKeys.Format.Medium] = "Medium",
                [LangKeys.Format.Minute] = "minute",
                [LangKeys.Format.Minutes] = "minutes",
                [LangKeys.Format.Nightmare] = "Nightmare",
                [LangKeys.Format.OilRig] = "Oil Rig",
                [LangKeys.Format.Second] = "second",
                [LangKeys.Format.Seconds] = "seconds",
                [LangKeys.Format.Updated] = "updated",
                [LangKeys.Permission.GroupCreated] = ":family: {time} Group `{0}` has been created",
                [LangKeys.Permission.GroupDeleted] = ":family: {time} Group `{0}` has been deleted",
                [LangKeys.Permission.UserGroupAdded] = ":family: {time} `{0}` `{1}` is added to group `{2}`",
                [LangKeys.Permission.UserGroupRemoved] = ":family: {time} `{0}` `{1}` is removed from group `{2}`",
                [LangKeys.Permission.UserPermissionGranted] = ":key: {time} `{0}` `{1}` is granted `{2}`",
                [LangKeys.Permission.UserPermissionRevoked] = ":key: {time} `{0}` `{1}` is revoked `{2}`",
                [LangKeys.Plugin.AdminHammerOff] = ":hammer: {time} AdminHammer enabled by `{0}`",
                [LangKeys.Plugin.AdminHammerOn] = ":hammer: {time} AdminHammer disabled by `{0}`",
                [LangKeys.Plugin.AdminRadarOff] = ":compass: {time} Admin Radar enabled by `{0}`",
                [LangKeys.Plugin.AdminRadarOn] = ":compass: {time} Admin Radar disabled by `{0}`",
                [LangKeys.Plugin.ClanCreated] = ":family_mwgb: {time} **{0}** clan was created",
                [LangKeys.Plugin.ClanDisbanded] = ":family_mwgb: {time} **{0}** clan was disbanded",
                [LangKeys.Plugin.DangerousTreasuresEnded] = ":pirate_flag: {time} Dangerous Treasures event at `{0}` is ended",
                [LangKeys.Plugin.DangerousTreasuresStarted] = ":pirate_flag: {time} Dangerous Treasures started at `{0}`",
                [LangKeys.Plugin.DeathNotes] = ":skull_crossbones: {time} {0}",
                [LangKeys.Plugin.Duel] = ":crossed_swords: {time} `{0}` has defeated `{1}` in a duel",
                [LangKeys.Plugin.GodmodeOff] = ":angel: {time} Godmode disabled for `{0}`",
                [LangKeys.Plugin.GodmodeOn] = ":angel: {time} Godmode enabled for `{0}`",
                [LangKeys.Plugin.NTeleportation] = ":cyclone: {time} `{0}` teleported from `{1}` `{2}` to `{3}` `{4}`",
                [LangKeys.Plugin.PersonalHelicopter] = ":dagger: {time} Personal Helicopter incoming `{0}`",
                [LangKeys.Plugin.PrivateMessage] = ":envelope: {time} PM from `{0}` to `{1}`: {2}",
                [LangKeys.Plugin.RaidableBaseCompleted] = ":homes: {time} {1} Raidable Base owned by {2} at `{0}` has been raided by **{3}**",
                [LangKeys.Plugin.RaidableBaseEnded] = ":homes: {time} {1} Raidable Base at `{0}` has ended",
                [LangKeys.Plugin.RaidableBaseStarted] = ":homes: {time} {1} Raidable Base spawned at `{0}`",
                [LangKeys.Plugin.RustKits] = ":shopping_bags: {time} `{0}` redeemed a kit `{1}`",
                [LangKeys.Plugin.TimedGroupAdded] = ":timer: {time} `{0}` `{1}` is added to `{2}` for {3}",
                [LangKeys.Plugin.TimedGroupExtended] = ":timer: {time} `{0}` `{1}` timed group `{2}` is extended to {3}",
                [LangKeys.Plugin.TimedPermissionExtended] = ":timer: {time} `{0}` `{1}` timed permission `{2}` is extended to {3}",
                [LangKeys.Plugin.TimedPermissionGranted] = ":timer: {time} `{0}` `{1}` is granted `{2}` for {3}",
                [LangKeys.Plugin.VanishOff] = ":ghost: {time} Vanish: Disabled for `{0}`",
                [LangKeys.Plugin.VanishOn] = ":ghost: {time} Vanish: Enabled for `{0}`",
            }, this);
        }

        #endregion Localization

        #region Events Hooks

        private void OnAdminHammerEnabled(BasePlayer player)
        {
            LogToConsole($"AdminHammer enabled by {player.UserIDString} {player.displayName}");

            DiscordSendMessage(Lang(LangKeys.Plugin.AdminHammerOff, null, ReplaceChars(player.displayName)), _configData.AdminHammerSettings.WebhookURL);
        }

        private void OnAdminHammerDisabled(BasePlayer player)
        {
            LogToConsole($"AdminHammer disabled by {player.UserIDString} {player.displayName}");

            DiscordSendMessage(Lang(LangKeys.Plugin.AdminHammerOn, null, ReplaceChars(player.displayName)), _configData.AdminHammerSettings.WebhookURL);
        }

        private void OnBetterChatMuted(IPlayer target, IPlayer initiator, string reason)
        {
            LogToConsole($"{target.Name} was muted by {initiator.Name} for ever ({reason})");

            DiscordSendMessage(Lang(LangKeys.Event.UserMuted, null, ReplaceChars(target.Name), ReplaceChars(initiator.Name), "ever", ReplaceChars(reason)), _configData.UserMutedSettings.WebhookURL);
        }

        private void OnBetterChatMuteExpired(IPlayer player)
        {
            LogToConsole($"{player.Name} was unmuted by SERVER");

            DiscordSendMessage(Lang(LangKeys.Event.UserUnmuted, null, ReplaceChars(player.Name), "SERVER"), _configData.UserMutedSettings.WebhookURL);
        }

        private void OnBetterChatTimeMuted(IPlayer target, IPlayer initiator, TimeSpan time, string reason)
        {
            LogToConsole($"{target.Name} was muted by {initiator.Name} for {time.ToShortString()} ({reason})");

            DiscordSendMessage(Lang(LangKeys.Event.UserMuted, null, ReplaceChars(target.Name), ReplaceChars(initiator.Name), time.ToShortString(), ReplaceChars(reason)), _configData.UserMutedSettings.WebhookURL);
        }

        private void OnBetterChatUnmuted(IPlayer target, IPlayer initiator)
        {
            LogToConsole($"{target.Name} was unmuted by {initiator.Name}");

            DiscordSendMessage(Lang(LangKeys.Event.UserUnmuted, null, ReplaceChars(target.Name), ReplaceChars(initiator.Name)), _configData.UserMutedSettings.WebhookURL);
        }

        private void OnClanCreate(string tag)
        {
            LogToConsole($"{tag} clan was created");

            DiscordSendMessage(Lang(LangKeys.Plugin.ClanCreated, null, ReplaceChars(tag)), _configData.ClanSettings.WebhookURL);
        }

        private void OnClanDisbanded(string tag)
        {
            LogToConsole($"{tag} clan was disbanded");

            DiscordSendMessage(Lang(LangKeys.Plugin.ClanDisbanded, null, ReplaceChars(tag)), _configData.ClanSettings.WebhookURL);
        }

        private void OnDangerousEventStarted(Vector3 containerPos)
        {
            HandleDangerousTreasures(containerPos, LangKeys.Plugin.DangerousTreasuresStarted);
        }

        private void OnDangerousEventEnded(Vector3 containerPos)
        {
            HandleDangerousTreasures(containerPos, LangKeys.Plugin.DangerousTreasuresEnded);
        }

        private void OnDeathNotice(Dictionary<string, object> data, string message)
        {
            DiscordSendMessage(Lang(LangKeys.Plugin.DeathNotes, null, StripRustTags(Formatter.ToPlaintext(message))), _configData.PlayerDeathNotesSettings.WebhookURL);
        }

        private void OnDuelistDefeated(BasePlayer attacker, BasePlayer victim)
        {
            if (!attacker.IsValid() || !victim.IsValid())
            {
                return;
            }

            LogToConsole($"{attacker.displayName} has defeated {victim.displayName} in a duel");

            DiscordSendMessage(Lang(LangKeys.Plugin.Duel, null, ReplaceChars(attacker.displayName), ReplaceChars(victim.displayName)), _configData.DuelSettings.WebhookURL);
        }

        private void OnEntitySpawned(PatrolHelicopter entity)
        {
            NextTick(() => HandleEntity(entity));
        }

        private void OnEntitySpawned(BradleyAPC entity) => HandleEntity(entity);

        private void OnEntitySpawned(CargoPlane entity) => HandleEntity(entity);

        private void OnEntitySpawned(CargoShip entity) => HandleEntity(entity);

        private void OnEntitySpawned(CH47HelicopterAIController entity) => HandleEntity(entity);

        private void OnEntitySpawned(EggHuntEvent entity) => HandleEntity(entity);

        private void OnEntitySpawned(HackableLockedCrate entity) => HandleEntity(entity);

        private void OnEntitySpawned(SantaSleigh entity) => HandleEntity(entity);

        private void OnEntitySpawned(SupplyDrop entity) => HandleEntity(entity);

        private void OnEntitySpawned(XMasRefill entity) => HandleEntity(entity);

        private void OnEntityDeath(BasePlayer player, HitInfo info)
        {
            if (!player.IsValid() || info == null)
            {
                return;
            }

            if (_configData.GlobalSettings.HideNPC && (player.IsNpc || !player.userID.IsSteamId()))
            {
                return;
            }

            LogToConsole($"{player.displayName} died.");

            DiscordSendMessage(Lang(LangKeys.Event.Death, null, ReplaceChars(player.displayName)), _configData.PlayerDeathSettings.WebhookURL);
        }

        private void OnEntityKill(EggHuntEvent entity)
        {
            if (!entity.IsValid())
            {
                return;
            }

            List<EggHuntEvent.EggHunter> topHunters = Facepunch.Pool.Get<List<EggHuntEvent.EggHunter>>();
            foreach (KeyValuePair<ulong, EggHuntEvent.EggHunter> eggHunter in entity._eggHunters)
            {
                topHunters.Add(eggHunter.Value);
            }

            topHunters.Sort((EggHuntEvent.EggHunter a, EggHuntEvent.EggHunter b) => b.numEggs.CompareTo(a.numEggs));

            string winner;
            if (topHunters.Count > 0)
            {
                winner = ReplaceChars(topHunters[0].displayName);
            }
            else
            {
                winner = "No winner";
            }

            Facepunch.Pool.FreeUnmanaged(ref topHunters);

            bool isHalloween = entity is HalloweenHunt;
            if (isHalloween)
            {
                if (_configData.HalloweenSettings.Enabled)
                {
                    LogToConsole("Halloween Hunt Event has ended.The winner is " + winner);

                    DiscordSendMessage(Lang(LangKeys.Event.HalloweenWinner, null, winner), _configData.HalloweenSettings.WebhookURL);
                }
            }
            else
            {
                if (_configData.EasterSettings.Enabled)
                {
                    LogToConsole("Egg Hunt Event has ended.The winner is " + winner);

                    DiscordSendMessage(Lang(LangKeys.Event.EasterWinner, null, winner), _configData.EasterSettings.WebhookURL);
                }
            }
        }

        private void OnEntityKill(CargoShip cargoShip)
        {
            if (cargoShip.IsValid())
            {
                _cargoShips.Remove(cargoShip.net.ID.Value);
            }
        }

        private void OnExplosiveThrown(BasePlayer player, SupplySignal entity) => HandleSupplySignal(player, entity);

        private void OnExplosiveDropped(BasePlayer player, SupplySignal entity) => HandleSupplySignal(player, entity);

        private void OnGodmodeToggled(string playerID, bool enabled)
        {
            IPlayer player = covalence.Players.FindPlayerById(playerID);

            if (player == null)
            {
                return;
            }

            if (enabled)
            {
                LogToConsole($"Godmode disabled for {player.Id} {player.Name}");

                DiscordSendMessage(Lang(LangKeys.Plugin.GodmodeOn, null, ReplaceChars(player.Name)), _configData.GodmodeSettings.WebhookURL);

                return;
            }

            LogToConsole($"Godmode enabled for {player.Id} {player.Name}");

            DiscordSendMessage(Lang(LangKeys.Plugin.GodmodeOff, null, ReplaceChars(player.Name)), _configData.GodmodeSettings.WebhookURL);
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (_configData.PlayerConnectedSettings.Enabled)
            {
                LogToConsole($"Player {player.displayName} connected.");

                if (!_configData.GlobalSettings.HideAdmin || !player.IsAdmin)
                {
                    DiscordSendMessage(Lang(LangKeys.Event.PlayerConnected, null, ReplaceChars(player.displayName)), _configData.PlayerConnectedSettings.WebhookURL);
                }
            }

            if (_configData.PlayerConnectedInfoSettings.Enabled)
            {
                DiscordSendMessage(Lang(LangKeys.Event.PlayerConnectedInfo, null, ReplaceChars(player.displayName), player.UserIDString, player.net.connection.ipaddress.Split(':')[0]), _configData.PlayerConnectedInfoSettings.WebhookURL);
            }
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (!player.IsValid())
            {
                return;
            }

            LogToConsole($"Player {player.displayName} disconnected ({reason}).");

            if (!_configData.GlobalSettings.HideAdmin || !player.IsAdmin)
            {
                DiscordSendMessage(Lang(LangKeys.Event.PlayerDisconnected, null, ReplaceChars(player.displayName), ReplaceChars(reason)), _configData.PlayerDisconnectedSettings.WebhookURL);
            }
        }

        private void OnPlayerChat(BasePlayer player, string message, ConVar.Chat.ChatChannel channel)
        {
            if (!player.IsValid() || string.IsNullOrWhiteSpace(message))
            {
                return;
            }

            if (IsPluginLoaded(BetterChatMute))
            {
                _resultCall = BetterChatMute.Call("API_IsMuted", player.IPlayer);

                if (_resultCall is bool && (bool)_resultCall)
                {
                    return;
                }
            }

            if (_configData.GlobalSettings.UseAntiSpam && IsPluginLoaded(AntiSpam))
            {
                _resultCall = AntiSpam.Call("GetSpamFreeText", message);

                message = (_resultCall as string);

                if (string.IsNullOrWhiteSpace(message))
                {
                    return;
                }
            }

            if (_configData.GlobalSettings.UseUFilter && IsPluginLoaded(UFilter))
            {
                _sb.Clear();
                _sb.Append(message);

                _resultCall = UFilter.Call("Profanities", message);

                if (_resultCall is string[])
                {
                    _profanities = _resultCall as string[];
                }

                foreach (string profanity in _profanities)
                {
                    _sb.Replace(profanity, new('*', profanity.Length));
                }

                message = _sb.ToString();

                if (string.IsNullOrWhiteSpace(message))
                {
                    return;
                }
            }

            message = ReplaceChars(message);

            switch (channel)
            {
                case ConVar.Chat.ChatChannel.Global:
                case ConVar.Chat.ChatChannel.Local:
                    if (_configData.ChatSettings.Enabled)
                    {
                        DiscordSendMessage(Lang(LangKeys.Event.Chat, null, ReplaceChars(player.displayName), message), _configData.ChatSettings.WebhookURL);
                    }
                    break;
                case ConVar.Chat.ChatChannel.Team:
                    if (_configData.ChatTeamSettings.Enabled)
                    {
                        DiscordSendMessage(Lang(LangKeys.Event.ChatTeam, null, ReplaceChars(player.displayName), message), _configData.ChatTeamSettings.WebhookURL);
                    }
                    break;
            }
        }

        private void OnPlayerTeleported(BasePlayer player, Vector3 oldPosition, Vector3 newPosition)
        {
            LogToConsole($"NTeleportation {player.UserIDString} {player.displayName} from {oldPosition} to {newPosition}");

            DiscordSendMessage(Lang(LangKeys.Plugin.NTeleportation, null, ReplaceChars(player.displayName), GetGridPosition(oldPosition), oldPosition, GetGridPosition(newPosition), newPosition), _configData.NTeleportationSettings.WebhookURL);
        }

        private void OnPMProcessed(IPlayer sender, IPlayer target, string message)
        {
            LogToConsole($"PM from `{sender.Name}` to `{target.Name}`: {message}");

            DiscordSendMessage(Lang(LangKeys.Plugin.PrivateMessage, null, ReplaceChars(sender.Name), ReplaceChars(target.Name), ReplaceChars(message)), _configData.PrivateMessagesSettings.WebhookURL);
        }

        private void OnPlayerRespawned(BasePlayer player)
        {
            if (string.IsNullOrWhiteSpace(player?.displayName))
            {
                return;
            }

            LogToConsole($"{player.displayName} has been spawned at {GetGridPosition(player.transform.position)}");

            DiscordSendMessage(Lang(LangKeys.Event.PlayerRespawned, null, ReplaceChars(player.displayName), GetGridPosition(player.transform.position)), _configData.PlayerRespawnedSettings.WebhookURL);
        }

        private void OnRadarActivated(BasePlayer player)
        {
            LogToConsole($"Admin Radar enabled by {player.UserIDString} {player.displayName}");

            DiscordSendMessage(Lang(LangKeys.Plugin.AdminRadarOn, null, ReplaceChars(player.displayName)), _configData.AdminRadarSettings.WebhookURL);
        }

        private void OnRadarDeactivated(BasePlayer player)
        {
            LogToConsole($"Admin Radar disabled by {player.UserIDString} {player.displayName}");

            DiscordSendMessage(Lang(LangKeys.Plugin.AdminRadarOff, null, ReplaceChars(player.displayName)), _configData.AdminRadarSettings.WebhookURL);
        }

        private void OnRaidableBaseStarted(Vector3 raidPos, int difficulty)
        {
            HandleRaidableBase(raidPos, difficulty, LangKeys.Plugin.RaidableBaseStarted);
        }

        private void OnRaidableBaseEnded(Vector3 raidPos, int difficulty)
        {
            HandleRaidableBase(raidPos, difficulty, LangKeys.Plugin.RaidableBaseEnded);
        }

        private void OnRaidableBaseCompleted(Vector3 raidPos, int difficulty, bool allowPVP, string id, float spawnTime, float despawnTime, float loadTime, ulong ownerId, BasePlayer owner, List<BasePlayer> raiders)
        {
            HandleRaidableBase(raidPos, difficulty, LangKeys.Plugin.RaidableBaseCompleted, owner, raiders);
        }

        private void OnRconConnection(IPAddress ip)
        {
            LogToConsole($"RCON connection is opened from {ip}");

            DiscordSendMessage(Lang(LangKeys.Event.RconConnection, null, ip.ToString()), _configData.RconConnectionSettings.WebhookURL);
        }

        private void OnRconCommand(IPAddress ip, string command, string[] args)
        {
            foreach (string rconCommand in _configData.GlobalSettings.RCONCommandBlacklist)
            {
                if (command.ToLower().Equals(rconCommand.ToLower()))
                {
                    return;
                }
            }

            for (int i = 0; i < args.Length; i++)
            {
                command += $" {args[i]}";
            }

            LogToConsole($"RCON command {command} is run from {ip}");

            DiscordSendMessage(Lang(LangKeys.Event.RconCommand, null, command, ip), _configData.RconCommandSettings.WebhookURL);
        }

        private void OnSupplyDropLanded(SupplyDrop entity)
        {
            if (!entity.IsValid() || _listSupplyDrops.Contains(entity.net.ID.Value))
            {
                return;
            }

            LogToConsole($"SupplyDrop landed at {GetGridPosition(entity.transform.position)}");

            DiscordSendMessage(Lang(LangKeys.Event.SupplyDropLanded, null, GetGridPosition(entity.transform.position)), _configData.SupplyDropSettings.WebhookURL);

            _entityID = entity.net.ID.Value;

            _listSupplyDrops.Add(_entityID);

            timer.Once(60f, () => _listSupplyDrops.Remove(_entityID));
        }

        private void OnUserBanned(string name, string id, string ipAddress, string reason)
        {
            LogToConsole($"Player {name} ({id}) at {ipAddress} was banned: {reason}");

            DiscordSendMessage(Lang(LangKeys.Event.UserBanned, null, ReplaceChars(name), id, ipAddress, ReplaceChars(reason)), _configData.UserBannedSettings.WebhookURL);
        }

        private void OnUserKicked(IPlayer player, string reason)
        {
            LogToConsole($"Player {player.Name} ({player.Id}) was kicked ({reason})");

            DiscordSendMessage(Lang(LangKeys.Event.UserKicked, null, ReplaceChars(player.Name), player.Id, ReplaceChars(reason)), _configData.UserKickedSettings.WebhookURL);
        }

        private void OnUserUnbanned(string name, string id, string ipAddress)
        {
            LogToConsole($"Player {name} ({id}) at {ipAddress} was unbanned");

            DiscordSendMessage(Lang(LangKeys.Event.UserUnbanned, null, ReplaceChars(name), id, ipAddress), _configData.UserBannedSettings.WebhookURL);
        }

        private void OnUserNameUpdated(string id, string oldName, string newName)
        {
            if (oldName.Equals(newName) || oldName.Equals("Unnamed"))
            {
                return;
            }
            
            LogToConsole($"Player name changed from {oldName} to {newName} for ID {id}");

            DiscordSendMessage(Lang(LangKeys.Event.UserNameUpdated, null, ReplaceChars(oldName), ReplaceChars(newName), id), _configData.UserNameUpdateSettings.WebhookURL);
        }

        private void OnServerMessage(string message, string name, string color, ulong id)
        {
            LogToConsole($"ServerMessage: {message}");

            DiscordSendMessage(Lang(LangKeys.Event.ServerMessage, null, message), _configData.ServerMessagesSettings.WebhookURL);
        }

        private void OnKitRedeemed(BasePlayer player, string kitName)
        {
            LogToConsole($"{player.UserIDString} {player.displayName} redeemed a kit {kitName}");

            DiscordSendMessage(Lang(LangKeys.Plugin.RustKits, null, ReplaceChars(player.displayName), ReplaceChars(kitName)), _configData.RustKitsSettings.WebhookURL);
        }

        private void OnVanishDisappear(BasePlayer player)
        {
            LogToConsole($"Vanish: Enabled ({player.UserIDString} {player.displayName})");

            DiscordSendMessage(Lang(LangKeys.Plugin.VanishOn, null, ReplaceChars(player.displayName)), _configData.VanishSettings.WebhookURL);
        }

        private void OnVanishReappear(BasePlayer player)
        {
            LogToConsole($"Vanish: Disabled ({player.UserIDString} {player.displayName})");

            DiscordSendMessage(Lang(LangKeys.Plugin.VanishOff, null, ReplaceChars(player.displayName)), _configData.VanishSettings.WebhookURL);
        }

        #region Team Hooks

        private void OnTeamCreated(BasePlayer player, RelationshipManager.PlayerTeam team) => HandleTeam(team, TeamEventType.Created);

        private void OnTeamDisbanded(RelationshipManager.PlayerTeam team) => HandleTeam(team, TeamEventType.Disbanded);

        private void OnTeamUpdated(ulong currentTeam, RelationshipManager.PlayerTeam team, BasePlayer player)
        {
            NextTick( () => {
                if (team.members.Count > 0)
                {
                    HandleTeam(team, TeamEventType.Updated);
                }
            });
        }

        private void OnTeamPromote(RelationshipManager.PlayerTeam team, BasePlayer newLeader)
        {
            NextTick( () => { HandleTeam(team, TeamEventType.Updated); });
        }

        private void OnTeamLeave(RelationshipManager.PlayerTeam team, BasePlayer player)
        {
            NextTick( () => {
                if (team?.members?.Count > 0)
                {
                    HandleTeam(team, TeamEventType.Updated);
                }
            });
        }

        private void OnTeamKick(RelationshipManager.PlayerTeam team, BasePlayer player, ulong target)
        {
            NextTick( () => { HandleTeam(team, TeamEventType.Updated); });
        }

        private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam team, BasePlayer player)
        {
            NextTick( () => { HandleTeam(team, TeamEventType.Updated); });
        }

        #e
// ... [Code preview truncated due to length. Full source in attached file] ...

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