using Newtonsoft.Json; using Oxide.Core; using Oxide.Core.Plugins; using Oxide.Game.Rust.Cui; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace Oxide.Plugins { [Info("Monument Player Settings", "YaMang-w-", "1.0.4")] [Description("Block certain actions, commands, etc. within the monument. (to teleport)")] class MonumentPlayerSettings : RustPlugin { #region Fleids [PluginReference] private Plugin NoEscape; private const string OutPostPrefab = "assets/bundled/prefabs/autospawn/monument/medium/compound.prefab"; private const string BanditTownPrefab = "assets/bundled/prefabs/autospawn/monument/medium/bandit_town.prefab"; private const string MainUI = "MonumentContainer"; private const string UsePermission = "monumentplayersettings.use"; private const string BypassPermission = "monumentplayersettings.bypass"; Dictionary teleportTimer = new Dictionary(); Dictionary monumentLists = new Dictionary(); #endregion #region Hook void OnServerInitialized() { permission.RegisterPermission(UsePermission, this); permission.RegisterPermission(BypassPermission, this); if (_config.tpMonumentSetting.useBandit || _config.tpMonumentSetting.useOutPost) cmd.AddChatCommand(_config.generalSettings.Commands, this, nameof(MonumentTPCMD)); if (!_config.monumentSetting.blockInMSpray) Unsubscribe(nameof(OnSprayCreate)); if (!_config.monumentSetting.blockInMPickup) Unsubscribe(nameof(CanPickupEntity)); if (_config.monumentSetting.blockInMCommands.Count == 0) Unsubscribe(nameof(OnPlayerCommand)); if (_config.monumentSetting.blockInMActiveItems.Count == 0) Unsubscribe(nameof(OnActiveItemChanged)); var outpost = FindMonumentPosition(OutPostPrefab); if (outpost == new Vector3()) return; monumentLists.Add("outpost", outpost); var bandit = FindMonumentPosition(BanditTownPrefab); if (bandit == new Vector3()) return; monumentLists.Add("bandit", bandit); } void Unload() { foreach (var player in BasePlayer.activePlayerList) { CuiHelper.DestroyUi(player, MainUI); } } void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) { if (player == null) return; bool find = InMonumentPosition(player); if (find) { var held = player.GetHeldEntity(); if (held == null) return; var item = held.GetItem() ?? null; if (!_config.monumentSetting.blockInMActiveItems.Contains(item.info.shortname)) return; held.SetHeld(false); held.SendNetworkUpdate(); player.SendNetworkUpdate(); Messages(player, Lang("ActiveItemsCannot", item.name ?? item.info.displayName.english)); } } object OnPlayerCommand(BasePlayer player, string command, string[] args) { if (!_config.monumentSetting.blockInMCommands.Contains(command)) return null; bool find = InMonumentPosition(player); if (find) { Messages(player, Lang("CommandsCannot", command)); return true; } return null; } bool CanPickupEntity(BasePlayer player, BaseEntity entity) { bool find = InMonumentPosition(player); if (find) { Messages(player, Lang("PickupCannot")); return false; } return true; } private object OnSprayCreate(SprayCan spray, Vector3 position, Quaternion rotation) { BasePlayer player = spray.GetOwnerPlayer(); bool find = InMonumentPosition(player); if (find) { Messages(player, Lang("SparayCannot")); return false; } return null; } #endregion #region Commands private void MonumentTPCMD(BasePlayer player, string command, string[] args) { if(!permission.UserHasPermission(player.UserIDString, UsePermission)) { Messages(player, Lang("NoPerm")); return; } MonumentTeleportUI(player); } [ConsoleCommand("teleport.monument")] private void MonumentTeleport(ConsoleSystem.Arg arg) { var player = arg.Player(); if (player == null) return; if (arg.Args[0] != "close" && arg.Args[0] != "cancel") { var err = SetFlags(player); if (err != null) { Messages(player, $"{err}"); return; } } Vector3 pos = new Vector3(); switch (arg.Args[0]) { case "outpost": if (teleportTimer.ContainsKey(player.UserIDString)) { Messages(player, Lang("CancelTp")); return; } pos = monumentLists["outpost"]; Messages(player, Lang("TryTp", Lang("Outpost"), _config.tpMonumentSetting.cooltimeOutPost)); var OutpostTimer = timer.Once(_config.tpMonumentSetting.cooltimeOutPost, () => { TeleportPlayer(player, pos, Lang("Outpost")); }); teleportTimer.Add(player.UserIDString, OutpostTimer); CuiHelper.DestroyUi(player, MainUI); break; case "bandit": if (teleportTimer.ContainsKey(player.UserIDString)) { Messages(player, Lang("CancelTp")); return; } pos = monumentLists["bandit"]; Messages(player, Lang("TryTp", Lang("Bandit"), _config.tpMonumentSetting.cooltimeBandit)); var Bandittimer = timer.Once(_config.tpMonumentSetting.cooltimeBandit, () => { TeleportPlayer(player, pos, Lang("Bandit")); }); teleportTimer.Add(player.UserIDString, Bandittimer); CuiHelper.DestroyUi(player, MainUI); break; case "close": CuiHelper.DestroyUi(player, MainUI); break; case "cancel": if (teleportTimer.ContainsKey(player.UserIDString)) { Messages(player, Lang("CancelTp")); teleportTimer[player.UserIDString].Destroy(); teleportTimer.Remove(player.UserIDString); } else { Messages(player, "There is nothing to cancel."); CuiHelper.DestroyUi(player, MainUI); } break; } } #endregion #region Config private ConfigData _config; private class ConfigData { [JsonProperty(PropertyName = "General Settings")] public GeneralSettings generalSettings { get; set; } [JsonProperty(PropertyName = "Teleport Settings")] public TPMonumentSetting tpMonumentSetting { get; set; } [JsonProperty(PropertyName = "Monument Settings")] public MonumentSetting monumentSetting { get; set; } public Oxide.Core.VersionNumber Version { get; set; } } public class GeneralSettings { [JsonProperty(PropertyName = "Prefix", Order = 1)] public string Prefix { get; set; } [JsonProperty(PropertyName = "SteamID", Order = 2)] public ulong SteamID { get; set; } [JsonProperty(PropertyName = "Commands", Order = 3)] public string Commands { get; set; } } public class TPMonumentSetting { [JsonProperty(PropertyName = "Use teleport Outpost?")] public bool useOutPost { get; set; } [JsonProperty(PropertyName = "teleport cooltime Outpost")] public float cooltimeOutPost { get; set; } [JsonProperty(PropertyName = "Use teleport Bandit?")] public bool useBandit { get; set; } [JsonProperty(PropertyName = "teleport cooltime Bandit")] public float cooltimeBandit { get; set; } } public class MonumentSetting { [JsonProperty(PropertyName = "Block commands in monuments")] public List blockInMCommands { get; set; } [JsonProperty(PropertyName = "Block Spary in monuments")] public bool blockInMSpray { get; set; } [JsonProperty(PropertyName = "Block Active Item in monuments")] public List blockInMActiveItems { get; set; } [JsonProperty(PropertyName = "Block Pickup in monuments")] public bool blockInMPickup { get; set; } } protected override void LoadConfig() { base.LoadConfig(); try { _config = Config.ReadObject(); if (_config == null) throw new Exception(); Puts($"{_config.Version} | {Version}"); if (_config.Version < Version) UpdateConfigValues(); } catch { Config.WriteObject(_config, false, $"{Interface.Oxide.ConfigDirectory}/{Name}_BackupError.json"); PrintError("An error occurred in the config\nFind the CommandsItem_BackupError file."); } SaveConfig(); } protected override void LoadDefaultConfig() => _config = GetBaseConfig(); private ConfigData GetBaseConfig() { return new ConfigData { generalSettings = new GeneralSettings { Prefix = "[Monument-Settings]\n", SteamID = 0, Commands = "mtp", }, tpMonumentSetting = new TPMonumentSetting { useBandit = true, cooltimeBandit = 15f, useOutPost = true, cooltimeOutPost = 15f }, monumentSetting = new MonumentSetting { blockInMSpray = true, blockInMPickup = true, blockInMActiveItems = new List { "fun.trumpet" }, blockInMCommands = new List { "remove" } }, Version = Version }; } protected override void SaveConfig() => Config.WriteObject(_config, true); private void UpdateConfigValues() { PrintWarning("Config update detected! Updating config values..."); Config.WriteObject(_config, false, $"{Interface.Oxide.ConfigDirectory}/{Name}_{_config.Version}.json"); _config.Version = Version; PrintWarning("Config update completed!"); } #endregion #region Lang protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { { "SparayCannot", "Spray cannot be use here." }, { "CommandsCannot", "{0} cannot be use here." }, { "PickupCannot", "cannot be pickup here." }, { "ActiveItemsCannot", "{0} cannot be held here." }, { "TryTp", "Teleport to {0} after {1} seconds" }, { "CompleteTp", "{0} Teleport!" }, { "PlayerInFlagsTp", "{0} Teleporting Canceled | Reason: {1}!" }, { "CancelTp", "Canceled Teleport" }, { "AlreadyTp", "Already Teleporting / cancel press" }, { "Outpost", "Outpost"}, { "Bandit", "Bandit Camp" }, { "NoPerm", "You have not permission" } }, this); } private string Lang(string key, params object[] args) { return string.Format(lang.GetMessage(key, this), args); } #endregion #region Helper private void Messages(BasePlayer player, string text) => player.SendConsoleCommand("chat.add", 2, _config.generalSettings.SteamID, $"{_config.generalSettings.Prefix} {text}"); private string SetFlags(BasePlayer player) { if (player.isMounted) { return "mounted"; } if (player.IsWounded()) { return "Wounded"; } if (player.IsSwimming()) { return "Swimming"; } if (Convert.ToBoolean(NoEscape?.Call("IsBlocked", player))) { return "Raid or Combat Blocked"; } if (player.IsDead()) { return "Dead"; } if (player.IsHostile()) { return "It's impossible because you're hostile"; } if (player.IsBuildingBlocked()) { return "Your in a building blocked"; } return null; } private bool CheckFlags(BasePlayer player) { if (SetFlags(player) != null) return false; else return true; } private bool InMonumentPosition(BasePlayer player) { bool find = false; if (permission.UserHasPermission(player.UserIDString, BypassPermission)) return false; foreach (var item in TerrainMeta.Path.Monuments) { if (item.name.ToLower() == BanditTownPrefab) { find = item.IsInBounds(player.transform.position); if (find) break; else continue; } if (item.name.ToLower() == OutPostPrefab) { find = item.IsInBounds(player.transform.position); if (find) break; else continue; } } return find; } private Vector3 FindMonumentPosition(string monumentPrefab) { var monumentPosition = TerrainMeta.Path.Monuments .Where(m => m.name.ToLower() == monumentPrefab) .FirstOrDefault()? .transform .position; if (null == monumentPosition) Puts($"Failed to find a location for Monument: {monumentPrefab}"); return monumentPosition ?? new Vector3(); } private bool TeleportPlayer(BasePlayer player, Vector3 pos, string text) { var err = SetFlags(player); if (err != null) { if (teleportTimer.ContainsKey(player.UserIDString)) { Messages(player, Lang("PlayerInFlagsTp", text, err)); teleportTimer[player.UserIDString].Destroy(); teleportTimer.Remove(player.UserIDString); } return false; } RaycastHit hit; if (!Physics.Raycast(new Ray(pos + Vector3.up * 10, Vector3.down), out hit)) { Messages(player, "[ERROR] - Monument not found"); return false; } pos = hit.point; if (teleportTimer.ContainsKey(player.UserIDString)) { player.Teleport(pos); teleportTimer[player.UserIDString].Destroy(); teleportTimer.Remove(player.UserIDString); } return true; } private static string HexToCuiColor(string HEX, float Alpha = 100) { if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF"; var str = HEX.Trim('#'); if (str.Length != 6) throw new Exception(HEX); var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber); var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber); var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber); return $"{(double)r / 255} {(double)g / 255} {(double)b / 255} {Alpha / 100f}"; } #endregion #region UI private void MonumentTeleportUI(BasePlayer player) { CuiHelper.DestroyUi(player, MainUI); var container = new CuiElementContainer(); container.Add(new CuiPanel { CursorEnabled = true, Image = { Color = "0 0 0 0.3529412", }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-150 -69.992", OffsetMax = "150 70.008" } }, "Overlay", MainUI); container.Add(new CuiPanel { CursorEnabled = false, Image = { Color = "0.1607843 0.6705883 0.5294118 1" }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-150 39.847", OffsetMax = "150 69.847" } }, MainUI, "TitlePanel"); container.Add(new CuiButton { Button = { Color = "0.41 0.101 0.67 1", Command = "teleport.monument cancel" }, Text = { Text = "Cancel", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "74.174 -15.154", OffsetMax = "121.038 15.153" } }, "TitlePanel", "CancelBtn"); container.Add(new CuiButton { Button = { Color = "0 0 0 0.87", Command = "teleport.monument close" }, Text = { Text = "X", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "121.037 -15.154", OffsetMax = "150.004 15.153" } }, "TitlePanel", "CloseBtn"); container.Add(new CuiElement { Name = "Title_Text", Parent = "TitlePanel", Components = { new CuiTextComponent { Text = $"Monument Teleport - [ {(CheckFlags(player) ? "Available" : "Impossible")} ]", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.UpperLeft, Color = "1 1 1 1" }, new CuiOutlineComponent { Color = "0 0 0 0.5", Distance = "1 -1" }, new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-144.735 -10.861", OffsetMax = "74.172 10.861" } } }); if(_config.tpMonumentSetting.useBandit) { container.Add(new CuiButton { Button = { Color = "0 0 0 0.87", Command = "teleport.monument bandit" }, Text = { Text = $"Bandit Camp\n\n\n[ {_config.tpMonumentSetting.cooltimeBandit}s ]", Font = "robotocondensed-regular.ttf", FontSize = 17, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FadeIn = 2 }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-150 -70.002", OffsetMax = "0 39.848" } }, MainUI, "BanditBtn"); } else { if (_config.tpMonumentSetting.useOutPost) { container.Add(new CuiButton { Button = { Color = "0 0 0 0.87", Command = "teleport.monument outpost" }, Text = { Text = $"Outpost\n\n\n[ {_config.tpMonumentSetting.cooltimeBandit}s ]", Font = "robotocondensed-regular.ttf", FontSize = 17, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FadeIn = 2 }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-150 -70.002", OffsetMax = "0 39.848" } }, MainUI, "OutpostBtn"); return; } } if(_config.tpMonumentSetting.useOutPost) { container.Add(new CuiButton { Button = { Color = "0 0 0 0.87", Command = "teleport.monument outpost" }, Text = { Text = $"Outpost\n\n\n[ {_config.tpMonumentSetting.cooltimeBandit}s ]", Font = "robotocondensed-regular.ttf", FontSize = 17, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FadeIn = 2 }, RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "0 -70.002", OffsetMax = "150 39.848" } }, MainUI, "OutpostBtn"); } CuiHelper.AddUi(player, container); } #endregion } }