Guest User

AutoLock

a guest
Feb 3rd, 2023
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.99 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using JetBrains.Annotations;
  5. using Newtonsoft.Json;
  6. using Oxide.Core;
  7. using Oxide.Core.Plugins;
  8. using UnityEngine;
  9. using Object = UnityEngine.Object;
  10. using Random = Oxide.Core.Random;
  11.  
  12. namespace Oxide.Plugins
  13. {
  14.     [Info("Auto Lock", "birthdates", "2.4.5")]
  15.     [Description("Automatically adds a codelock to a lockable entity with a set pin")]
  16.     public class AutoLock : RustPlugin
  17.     {
  18.         #region Variables
  19.  
  20.         private const string PermissionUse = "autolock.use";
  21.         private const string PermissionItemBypass = "autolock.item.bypass";
  22.  
  23.         private readonly Dictionary<BasePlayer, TimedCodeLock> _awaitingResponse =
  24.             new Dictionary<BasePlayer, TimedCodeLock>();
  25.  
  26.         [UsedImplicitly] [PluginReference("NoEscape")]
  27.         private Plugin _noEscape;
  28.  
  29.         private struct TimedCodeLock
  30.         {
  31.             public CodeLock CodeLock { get; set; }
  32.             public DateTime Expiry { get; set; }
  33.         }
  34.  
  35.         #endregion
  36.  
  37.         #region Hooks
  38.  
  39.         [UsedImplicitly]
  40.         private void Init()
  41.         {
  42.             LoadConfig();
  43.             permission.RegisterPermission(PermissionUse, this);
  44.             permission.RegisterPermission(PermissionItemBypass, this);
  45.             _data = Interface.Oxide.DataFileSystem.ReadObject<Data>(Name);
  46.  
  47.             cmd.AddChatCommand("autolock", this, ChatCommand);
  48.             cmd.AddChatCommand("al", this, ChatCommand);
  49.             if (_config.CodeLockExpiry <= 0f) Unsubscribe(nameof(OnServerInitialized));
  50.         }
  51.  
  52.         [UsedImplicitly]
  53.         private void OnServerInitialized()
  54.         {
  55.             timer.Every(3f, () =>
  56.             {
  57.                 for (var i = _awaitingResponse.Count - 1; i > 0; i--)
  58.                 {
  59.                     var timedLock = _awaitingResponse.ElementAt(i);
  60.                     if (timedLock.Value.Expiry > DateTime.UtcNow) continue;
  61.                     _awaitingResponse.Remove(timedLock.Key);
  62.                 }
  63.             });
  64.         }
  65.  
  66.         [UsedImplicitly]
  67.         private void OnEntityBuilt(HeldEntity plan, GameObject go)
  68.         {
  69.             var player = plan.GetOwnerPlayer();
  70.             if (player == null) return;
  71.             if (!permission.UserHasPermission(player.UserIDString, PermissionUse)) return;
  72.             var entity = go.ToBaseEntity() as DecayEntity;
  73.             if (entity == null || _config.Disabled.Contains(entity.PrefabName)) return;
  74.             var container = entity as StorageContainer;
  75.             if (entity.IsLocked() || container != null && container.inventorySlots < 12 ||
  76.                 !container && !(entity is AnimatedBuildingBlock)) return;
  77.             if (_noEscape != null)
  78.             {
  79.                 if (_config.NoEscapeSettings.BlockRaid && _noEscape.Call<bool>("IsRaidBlocked", player.UserIDString))
  80.                 {
  81.                     player.ChatMessage(lang.GetMessage("RaidBlocked", this, player.UserIDString));
  82.                     return;
  83.                 }
  84.  
  85.                 if (_config.NoEscapeSettings.BlockCombat &&
  86.                     _noEscape.Call<bool>("IsCombatBlocked", player.UserIDString))
  87.                 {
  88.                     player.ChatMessage(lang.GetMessage("CombatBlocked", this, player.UserIDString));
  89.                     return;
  90.                 }
  91.             }
  92.  
  93.             var playerData = CreateDataIfAbsent(player.UserIDString);
  94.             if (!playerData.Enabled || !HasCodeLock(player)) return;
  95.             var code = GameManager.server.CreateEntity("assets/prefabs/locks/keypad/lock.code.prefab") as CodeLock;
  96.             if (code != null)
  97.             {
  98.                 code.gameObject.Identity();
  99.                 code.SetParent(entity, entity.GetSlotAnchorName(BaseEntity.Slot.Lock));
  100.                 code.Spawn();
  101.                 code.code = playerData.Code;
  102.                 code.hasCode = true;
  103.                 entity.SetSlot(BaseEntity.Slot.Lock, code);
  104.                 Effect.server.Run("assets/prefabs/locks/keypad/effects/lock-code-deploy.prefab",
  105.                     code.transform.position);
  106.                 code.whitelistPlayers.Add(player.userID);
  107.                 code.SetFlag(BaseEntity.Flags.Locked, true);
  108.             }
  109.  
  110.             TakeCodeLock(player);
  111.             player.ChatMessage(string.Format(lang.GetMessage("CodeAdded", this, player.UserIDString),
  112.                 player.net.connection.info.GetBool("global.streamermode") ? "****" : playerData.Code));
  113.         }
  114.  
  115.         private static string GetRandomCode()
  116.         {
  117.             return Random.Range(1000, 9999).ToString();
  118.         }
  119.  
  120.         [UsedImplicitly]
  121.         private void OnServerShutdown()
  122.         {
  123.             Unload();
  124.         }
  125.  
  126.         private void Unload()
  127.         {
  128.             SaveData();
  129.             foreach (var timedLock in _awaitingResponse.Values.Where(timedLock => !timedLock.CodeLock.IsDestroyed))
  130.                 timedLock.CodeLock.Kill();
  131.         }
  132.  
  133.         private PlayerData CreateDataIfAbsent(string id)
  134.         {
  135.             PlayerData playerData;
  136.             if (_data.Codes.TryGetValue(id, out playerData)) return playerData;
  137.             _data.Codes.Add(id, playerData = new PlayerData
  138.             {
  139.                 Code = GetRandomCode(),
  140.                 Enabled = true
  141.             });
  142.             return playerData;
  143.         }
  144.  
  145.         #endregion
  146.  
  147.         #region Command
  148.  
  149.         private void ChatCommand(BasePlayer player, string label, string[] args)
  150.         {
  151.             if (!permission.UserHasPermission(player.UserIDString, PermissionUse))
  152.             {
  153.                 player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
  154.                 return;
  155.             }
  156.  
  157.             if (args.Length < 1)
  158.             {
  159.                 player.ChatMessage(string.Format(lang.GetMessage("InvalidArgs", this, player.UserIDString), label));
  160.                 return;
  161.             }
  162.  
  163.             CreateDataIfAbsent(player.UserIDString);
  164.             switch (args[0].ToLower())
  165.             {
  166.                 case "code":
  167.                     AttemptToChangeCode(player, args);
  168.                     break;
  169.                 case "toggle":
  170.                     player.ChatMessage(lang.GetMessage(Toggle(player) ? "Enabled" : "Disabled", this,
  171.                         player.UserIDString));
  172.                     break;
  173.                 default:
  174.                     player.ChatMessage(string.Format(lang.GetMessage("InvalidArgs", this, player.UserIDString), label));
  175.                     break;
  176.             }
  177.         }
  178.  
  179.         private void AttemptToChangeCode(BasePlayer player, string[] args)
  180.         {
  181.             if (args.Length == 2)
  182.             {
  183.                 string code = new string(args[1].Where(c=>(Char.IsDigit(c))).ToArray());
  184.                 if (code.Length == 4)
  185.                 {
  186.                     var pData = _data.Codes[player.UserIDString];
  187.                     pData.Code = code;
  188.                     player.ChatMessage(string.Format(lang.GetMessage("CodeUpdated", this, player.UserIDString),
  189.                     player.net.connection.info.GetBool("global.streamermode") ? "****" : code));
  190.                     return;
  191.                 }
  192.             }
  193.             player.ChatMessage(lang.GetMessage("InvalidCodeArgs", this, player.UserIDString));
  194.         }
  195.  
  196.         private static bool HasCodeLock(BasePlayer player)
  197.         {
  198.             return player.IPlayer.HasPermission(PermissionItemBypass) || player.inventory.FindItemID(1159991980) != null;
  199.         }
  200.  
  201.         private static void TakeCodeLock(BasePlayer player)
  202.         {
  203.             if (!player.IPlayer.HasPermission(PermissionItemBypass))
  204.                 player.inventory.Take(null, 1159991980, 1);
  205.         }
  206.  
  207.         private bool Toggle(BasePlayer player)
  208.         {
  209.             var data = _data.Codes[player.UserIDString];
  210.             var newToggle = !data.Enabled;
  211.             data.Enabled = newToggle;
  212.             return newToggle;
  213.         }
  214.  
  215.         #endregion
  216.  
  217.         #region Configuration & Language
  218.  
  219.         private ConfigFile _config;
  220.         private Data _data;
  221.  
  222.         private class PlayerData
  223.         {
  224.             public string Code;
  225.             public bool Enabled;
  226.         }
  227.  
  228.         private class Data
  229.         {
  230.             public readonly Dictionary<string, PlayerData> Codes = new Dictionary<string, PlayerData>();
  231.         }
  232.  
  233.         protected override void LoadDefaultMessages()
  234.         {
  235.             lang.RegisterMessages(new Dictionary<string, string>
  236.             {
  237.                 {"CodeAdded", "Codelock placed with code {0}."},
  238.                 {"Disabled", "You have disabled auto locks."},
  239.                 {"Enabled", "You have enabled auto locks."},
  240.                 {"CodeUpdated", "Your new code is {0}."},
  241.                 {"NoPermission", "You don't have permission."},
  242.                 {"InvalidArgs", "/{0} code|toggle|hide"},
  243.                 {"InvalidCodeArgs", "Invalid code format, Use command /al code (code), for example to set the code to 1234, Use command /al code 1234"},
  244.                 {"RaidBlocked", "The codelock wasn't automatically locked due to you being raid blocked!"},
  245.                 {"CombatBlocked", "The codelock wasn't automatically locked due to you being combat blocked!"}
  246.             }, this);
  247.         }
  248.  
  249.         public class ConfigFile
  250.         {
  251.             [JsonProperty("Code Lock Expiry Time (Seconds, put -1 if you want to disable)")]
  252.             public float CodeLockExpiry;
  253.  
  254.             [JsonProperty("Disabled Items (Prefabs)")]
  255.             public List<string> Disabled;
  256.  
  257.             [JsonProperty("No Escape")] public NoEscapeSettings NoEscapeSettings;
  258.  
  259.             public static ConfigFile DefaultConfig()
  260.             {
  261.                 return new ConfigFile
  262.                 {
  263.                     Disabled = new List<string>
  264.                     {
  265.                         "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab"
  266.                     },
  267.                     CodeLockExpiry = 10f,
  268.                     NoEscapeSettings = new NoEscapeSettings
  269.                     {
  270.                         BlockCombat = true,
  271.                         BlockRaid = true
  272.                     }
  273.                 };
  274.             }
  275.         }
  276.  
  277.         public class NoEscapeSettings
  278.         {
  279.             [JsonProperty("Block Auto Lock whilst in Combat?")]
  280.             public bool BlockCombat;
  281.  
  282.             [JsonProperty("Block Auto Lock whilst Raid Blocked?")]
  283.             public bool BlockRaid;
  284.         }
  285.  
  286.         private void SaveData()
  287.         {
  288.             Interface.Oxide.DataFileSystem.WriteObject(Name, _data);
  289.         }
  290.  
  291.         protected override void LoadConfig()
  292.         {
  293.             base.LoadConfig();
  294.             _config = Config.ReadObject<ConfigFile>();
  295.             if (_config == null) LoadDefaultConfig();
  296.         }
  297.  
  298.         protected override void LoadDefaultConfig()
  299.         {
  300.             _config = ConfigFile.DefaultConfig();
  301.             PrintWarning("Default configuration has been loaded.");
  302.         }
  303.  
  304.         protected override void SaveConfig()
  305.         {
  306.             Config.WriteObject(_config);
  307.         }
  308.  
  309.         #endregion
  310.     }
  311. }
  312. //Generated with birthdates' Plugin Maker
Add Comment
Please, Sign In to add comment