/* * < ----- End-User License Agreement -----> * * You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of this software without the developer’s consent. * * THIS SOFTWARE IS PROVIDED BY IIIaKa AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Developer: IIIaKa * https://t.me/iiiaka * Discord: @iiiaka * https://github.com/IIIaKa * https://umod.org/user/IIIaKa * https://codefling.com/iiiaka * https://lone.design/vendor/iiiaka/ * https://www.patreon.com/iiiaka * https://boosty.to/iiiaka * GitHub repository page: https://github.com/IIIaKa/FreeRT * * uMod plugin page: https://umod.org/plugins/free-rt * uMod license: https://umod.org/plugins/free-rt#license * * Codefling plugin page: https://codefling.com/plugins/free-rt * Codefling license: https://codefling.com/plugins/free-rt?tab=downloads_field_4 * * Lone.Design plugin page: https://lone.design/product/free-rt/ * * Copyright © 2020-2024 IIIaKa */ using System; using System.Collections.Generic; using System.Linq; using Facepunch; using Newtonsoft.Json; using Oxide.Core; using UnityEngine; namespace Oxide.Plugins { [Info("Free RT", "IIIaKa", "0.1.8")] [Description("A simple plugin that allows players with permissions to open card-locked doors in Rad Towns without a card.")] class FreeRT : RustPlugin { #region ~Variables~ private const string PERMISSION_ALL = "freert.all", PERMISSION_GREEN = "freert.green", PERMISSION_BLUE = "freert.blue", PERMISSION_RED = "freert.red", Str_MsgNotAllowed = "MsgNotAllowed"; #endregion #region ~Configuration~ private static Configuration _config; private class Configuration { [JsonProperty(PropertyName = "Is it worth showing messages to players who don't have permissions?")] public bool ShowMessage = true; [JsonProperty(PropertyName = "Time in seconds(1-10) after which the door will close(hinged doors only)")] public float CloseTime = 5f; public Oxide.Core.VersionNumber Version; } protected override void LoadConfig() { base.LoadConfig(); try { _config = Config.ReadObject(); } catch (Exception ex) { PrintError($"{ex.Message}\n\n[{Title}] Your configuration file contains an error."); } if (_config == null || _config.Version == new VersionNumber()) { PrintWarning("The configuration file is not found or contains errors. Creating a new one..."); LoadDefaultConfig(); } else if (_config.Version < Version) { PrintWarning($"Your configuration file version({_config.Version}) is outdated. Updating it to {Version}."); _config.Version = Version; PrintWarning($"The configuration file has been successfully updated to version {_config.Version}!"); } _config.CloseTime = Mathf.Clamp(_config.CloseTime, 1f, 10f); SaveConfig(); } protected override void SaveConfig() => Config.WriteObject(_config); protected override void LoadDefaultConfig() => _config = new Configuration() { Version = Version }; #endregion #region ~Language~ protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["MsgNotAllowed"] = "You do not have permission to open this door without the card!" }, this); lang.RegisterMessages(new Dictionary { ["MsgNotAllowed"] = "У вас недостаточно прав для открытия этой двери без карточки!" }, this, "ru"); } #endregion #region ~Methods~ private bool TryOpenDoor(CardReader cardReader, BasePlayer player, Door door = null) { bool canOpen = false; if (permission.UserHasPermission(player.UserIDString, PERMISSION_ALL)) canOpen = true; else { switch (cardReader.accessLevel) { case 1: if (permission.UserHasPermission(player.UserIDString, PERMISSION_GREEN)) canOpen = true; break; case 2: if (permission.UserHasPermission(player.UserIDString, PERMISSION_BLUE)) canOpen = true; break; case 3: if (permission.UserHasPermission(player.UserIDString, PERMISSION_RED)) canOpen = true; break; default: break; } } if (canOpen) { if (door == null) cardReader.GrantCard(); else { door.SetFlag(BaseEntity.Flags.Open, true); timer.Once(_config.CloseTime, () => { if (door != null && (cardReader == null || !cardReader.HasFlag(BaseEntity.Flags.On))) door.SetFlag(BaseEntity.Flags.Open, false); }); } } else if (_config.ShowMessage) player.ChatMessage(lang.GetMessage(Str_MsgNotAllowed, this, player.UserIDString)); return canOpen; } #endregion #region ~Oxide Hooks~ void OnDoorKnocked(Door door, BasePlayer player) { if (door.isSecurityDoor && !door.IsOpen()) { var crList = Pool.Get>(); Vis.Entities(door.transform.position, 6f, crList); if (crList.Any()) TryOpenDoor(crList[0], player, door); Pool.FreeUnmanaged(ref crList); } } void OnSwitchToggled(ElectricSwitch electricSwitch, BasePlayer player) { var crList = Pool.Get>(); Vis.Entities(electricSwitch.transform.position, 2f, crList); if (crList.Any()) TryOpenDoor(crList[0], player); Pool.FreeUnmanaged(ref crList); } void OnButtonPress(PressButton button, BasePlayer player) { CardReader cardReader; foreach (var input in button.inputs) { cardReader = input.connectedTo?.ioEnt as CardReader; if (cardReader != null) { TryOpenDoor(cardReader, player); break; } } } void Init() { Unsubscribe(nameof(OnDoorKnocked)); Unsubscribe(nameof(OnSwitchToggled)); Unsubscribe(nameof(OnButtonPress)); permission.RegisterPermission(PERMISSION_ALL, this); permission.RegisterPermission(PERMISSION_GREEN, this); permission.RegisterPermission(PERMISSION_BLUE, this); permission.RegisterPermission(PERMISSION_RED, this); } void OnServerInitialized(bool initial) { Subscribe(nameof(OnDoorKnocked)); Subscribe(nameof(OnSwitchToggled)); Subscribe(nameof(OnButtonPress)); } #endregion #region ~Unload~ void Unload() { _config = null; } #endregion } }