/* * TODO: * - Add clan support <- 2.0.4 (NEXT) * - Add friend support <- 2.0.4 (NEXT) * - Lock fuel tank, hopper/dispenser and quarry toggeling seperatly <- 2.0.5 * - Quarry HP, repairs etc... <- 2.0.6 * - Economics/RP support <- 2.0.6 * - Discord support <- 2.0.7 * - Proper help text if a player has a certain permission <- 2.0.8 * - Quarry fuel consumption <- 2.0.8 * - Static quarry team share support <- 2.0.9 * - Static quarry friend share support <- 2.0.9 * - Static quarry clan share support <- 2.0.9 * - Static quarry added player support <- 2.0.9 * - More static quarry configuration options (like time until unlock after x amount of time, dome size etc.) <- 2.0.10 * - Add chat icon <- 2.0.11 * - Add UI <- 2.0.11 * * If you have suggestions my discord name is Enforcer#0696 or send it in the uMod help page :) */ using Newtonsoft.Json; using Oxide.Core; using Rust; using System.Collections.Generic; using System.Text; using UnityEngine; namespace Oxide.Plugins { [Info("Quarry Manager", "Enforcer", "2.0.3")] [Description("Manage a quarry that has been placed down")] class QuarryManager : RustPlugin { #region Fields private static QuarryManager Instance { get; set; } public static List staticQuarries = new List(); List sphereEntities = new List(); StringBuilder addedPlayerList = new StringBuilder(); bool teamAccess = false; bool addedPlayersAccess = false; static bool isStaticQuarryToggled { get; set; } static ulong staticQuarryToggler { get; set; } private static bool LockZone { get; set; } int count = 1; private const int layers = Layers.Mask.Default | Layers.Mask.Water | Layers.Solid; static MiningQuarry _quarry; #endregion #region Permissions // Permission to be able to use other commands private const string usePerm = "quarrymanager.use"; // Permission for team sharing private const string teamLockPerm = "quarrymanager.teamshare"; // Permission for individual player sharing private const string playerLockPerm = "quarrymanager.playershare"; // Permission for players to be able to bypass the static quarry dome private const string allowBypassPerm = "quarrymanager.allowbypass"; // Permission for admins private const string adminPerm = "quarrymanager.admin"; #endregion #region Init private void OnServerInitialized() { // Register the permissions permission.RegisterPermission(usePerm, this); permission.RegisterPermission(teamLockPerm, this); permission.RegisterPermission(playerLockPerm, this); permission.RegisterPermission(allowBypassPerm, this); permission.RegisterPermission(adminPerm, this); // Add the command from the config cmd.AddChatCommand(config.commands.qmCommand, this, nameof(QuarryShareCommand)); } private void Loaded() { // Load the data file LoadData(); // Checks if static quarry is enabled before searching for the prefab (Searching through all entities is bad I will change that in the next update) if (config.shareSettings.staticQuarrySharing.enableStaticQuarryShare) { foreach (var entity in BaseNetworkable.serverEntities) { FindStaticQuarry(entity); } } playerData = Interface.Oxide.DataFileSystem.ReadObject(Name); Instance = this; LockZone = false; isStaticQuarryToggled = false; } void Unload() { // Destory all spheres and checks if static quarries are enabled (Again searching through alot of entities is bad I will change it in the next update) if (config.shareSettings.staticQuarrySharing.enableStaticQuarryShare) { foreach (var spheres in BaseNetworkable.serverEntities) { var sphereE = spheres as SphereEntity; if (sphereEntities.Contains(sphereE)) { sphereE.Kill(); } } // Kills/destroys all existing static quarries foreach (var quarry in staticQuarries) { if (staticQuarries.Contains(quarry)) { StaticQuarry.Destroy(quarry); } } } config = null; } void OnNewSave() { if (config.generalSettings.wipeDataOnNewSave) { WipeData(); } } #endregion #region Config ConfigData config; private class ConfigData { [JsonProperty("General Settings")] public GeneralSettings generalSettings { get; set; } [JsonProperty("Commands")] public Commands commands { get; set; } [JsonProperty("Chat Settings")] public ChatSettings chatSettings { get; set; } [JsonProperty("Share Settings")] public ShareSettings shareSettings { get; set; } } public class GeneralSettings { [JsonProperty(PropertyName = "Wipe Data on new save")] public bool wipeDataOnNewSave { get; set; } } public class Commands { [JsonProperty(PropertyName = "Quarry Manager Command")] public string qmCommand { get; set; } } public class ChatSettings { [JsonProperty(PropertyName = "Chat prefix")] public string chatPrefix { get; set; } [JsonProperty(PropertyName = "Chat prefix colour")] public string chatPrefixColour { get; set; } [JsonProperty(PropertyName = "Chat icon")] public ulong chatIcon { get; set; } [JsonProperty("Quarry Share Messages")] public QuarryShareMessages quarryShareMessages { get; set; } [JsonProperty("RCON/Server Console Messages")] public ServerConsoleMessages serverConsoleMessages { get; set; } } public class QuarryShareMessages { [JsonProperty(PropertyName = "Print a message if team share is enabled")] public bool messageOnTeamShareEnabled { get; set; } [JsonProperty(PropertyName = "Print a message if team share is disabled")] public bool messageOnTeamShareDisabled { get; set; } [JsonProperty(PropertyName = "Print a message if a player is added to the share list")] public bool messageOnAddedToPlayerList { get; set; } [JsonProperty(PropertyName = "Print a message if a player is removed to the share list")] public bool messageOnRemovedFromPlayerList { get; set; } [JsonProperty(PropertyName = "Print a message if a player has activated a static quarry")] public bool messageOnStaticQuarryBeingUsed { get; set; } } public class ServerConsoleMessages { [JsonProperty(PropertyName = "Message the console if someone enables team share")] public bool messageRCONOnEnabledTeamShare { get; set; } [JsonProperty(PropertyName = "Message the console if someone disables team share")] public bool messageRCONOnDisableTeamShare { get; set; } [JsonProperty(PropertyName = "Message the console if someone is added to the share list")] public bool messageRCONOnAddedToShareList { get; set; } [JsonProperty(PropertyName = "Message the console if a player is removed to the share list")] public bool messageRCONOnRemovedToPlayerList { get; set; } [JsonProperty(PropertyName = "Message the console on static quarry lock activated")] public bool messageRCONOnStaticQuarryBeingUsed { get; set; } } public class ShareSettings { [JsonProperty(PropertyName = "Players can toggle other players quarries")] public bool canToggleQuarry { get; set; } [JsonProperty(PropertyName = "Lock quarry containers")] public bool canOpenQuarryContainers { get; set; } [JsonProperty("Team Sharing")] public TeamSharing teamSharing { get; set; } [JsonProperty("Individual Player Sharing")] public IndividualPlayerSharing individualPlayerSharing { get; set; } [JsonProperty("Static Quarry Sharing")] public StaticQuarrySharing staticQuarrySharing { get; set; } } public class TeamSharing { [JsonProperty(PropertyName = "Allow team to toggle the quarry")] public bool canTeamToggleQuarry { get; set; } [JsonProperty(PropertyName = "Allow team to open the quarries containers")] public bool canTeamOpenQuarry { get; set; } } public class IndividualPlayerSharing { [JsonProperty(PropertyName = "Allow added players to toggle the quarry")] public bool canAddedPlayersToggleQuarry { get; set; } [JsonProperty(PropertyName = "Allow added players to open the quarries containers")] public bool canAddedPlayersOpenQuarry { get; set; } } public class StaticQuarrySharing { [JsonProperty(PropertyName = "Enable static quarry lock")] public bool enableStaticQuarryShare { get; set; } [JsonProperty("Static Quarry Sharing")] public LocalSharing localSharing { get; set; } } public class LocalSharing { [JsonProperty(PropertyName = "If the player leaves the dome unlock the static quarry")] public bool unlockStaticQuarryOnExitDome { get; set; } } protected override void LoadConfig() { base.LoadConfig(); try { config = Config.ReadObject(); if (config == null) { LoadDefaultConfig(); } } catch { for (var i = 0; i < 3; i++) PrintError($"{Name}.json is corrupted! Recreating a new configuration"); LoadDefaultConfig(); return; } SaveConfig(); } protected override void LoadDefaultConfig() { config = new ConfigData() { generalSettings = new GeneralSettings() { wipeDataOnNewSave = true }, commands = new Commands() { qmCommand = "qm" }, chatSettings = new ChatSettings() { chatPrefix = "QuarryLocker >>", chatPrefixColour = "#FF6A13", chatIcon = 0, quarryShareMessages = new QuarryShareMessages() { messageOnTeamShareEnabled = true, messageOnTeamShareDisabled = true, messageOnAddedToPlayerList = true, messageOnRemovedFromPlayerList = true, messageOnStaticQuarryBeingUsed = true }, serverConsoleMessages = new ServerConsoleMessages() { messageRCONOnEnabledTeamShare = false, messageRCONOnDisableTeamShare = false, messageRCONOnAddedToShareList = false, messageRCONOnRemovedToPlayerList = false, messageRCONOnStaticQuarryBeingUsed = false } }, shareSettings = new ShareSettings() { canToggleQuarry = false, canOpenQuarryContainers = false, teamSharing = new TeamSharing() { canTeamToggleQuarry = true, canTeamOpenQuarry = true }, individualPlayerSharing = new IndividualPlayerSharing() { canAddedPlayersToggleQuarry = true, canAddedPlayersOpenQuarry = true }, staticQuarrySharing = new StaticQuarrySharing() { enableStaticQuarryShare = false, localSharing = new LocalSharing() { unlockStaticQuarryOnExitDome = false } } } }; PrintError("Creating a new configuration file!"); } protected override void SaveConfig() => Config.WriteObject(config); #endregion #region Data private PlayerData playerData; public class PlayerData { public Dictionary players = new Dictionary(); public User AddPlayer(ulong playerID, bool isTeamShareEnabled, Dictionary addedPlayers) { User player = new User(); players.Add(playerID, player); isTeamShareEnabled = player.EnabledTeamShare; addedPlayers = player.addedPlayers; return player; } public bool GetPlayer(ulong playerID) { if (players.ContainsKey(playerID)) { return true; } return false; } } public class User { public bool EnabledTeamShare; public Dictionary addedPlayers = new Dictionary(); } void LoadData() { // If the data does not exist then just make a new one try { playerData = Interface.Oxide.DataFileSystem.ReadObject(Name); } catch { Puts("QuarryManager.json was not found! Creating a new one."); playerData = new PlayerData(); } } private void SaveData() { Interface.Oxide.DataFileSystem.WriteObject(Name, playerData); } private void WipeData() { if (playerData == null) return; PrintWarning("[QuarryManager]: QuarryManager.json has been wiped!"); playerData.players.Clear(); } #endregion #region Lang protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { {"Info.Help", $"\n /{config.commands.qmCommand} h | help - Provides the following commands: \n /{config.commands.qmCommand} t | team - Enable/Disable quarry team share. \n /{config.commands.qmCommand} a | add - Adds a certain player that can access your quarry \n /{config.commands.qmCommand} r | remove - Removes a certain added player that can access your quarry \n /{config.commands.qmCommand} ra | removeall - Removes all added players that can access your quarry \n /{config.commands.qmCommand} l | list - Lists all added players that can access your quarry" }, {"Info.TeamSharingEnabled", "Your team can now access your quarry" }, {"Info.TeamSharingDisabled", "Your team can no longer access your quarry" }, {"Info.AddedPlayer", "{0} Can now access your quarries" }, {"Info.RemovedPlayer", "{0} Can no longer access your quarries" }, {"Info.RemovedAllPlayers", "No one can access your quarries that you have added" }, {"Info.NoAddedPlayers", "There are no players to list since you have not added any yet" }, {"Info.ListCurrentPlayers", "Players that are added that can access your quarries:\n{0}" }, {"Info.StaticQuarryActivated", "No one can access this quarry unless you leave the dome or the quarries fuel runs out" }, {"Info.MessageRconOnTeamShareEnabled", "{0}, enabled team share!"}, {"Info.MessageRconOnTeamShareDisabled", "{0}, disabled team share!"}, {"Info.MessageRconOnPlayerAdded", "{0}, added {1}"}, {"Info.MessageRconOnPlayerRemoved", "{0}, removed {1}"}, {"Info.MessageRconOnStaticQuarryActivated", "The static quarry has been activated at: {0} by {1}" }, {"Warning.NoPermission", "You don't have the required permissions to use this command" }, {"Warning.UnableToFindPlayer", "Unable to find the player!" }, {"Warning.UnableToAddSelf", "You cannot add yourself" }, {"Warning.UnableToAccessContainer", "You cannot access this quarry, since you are not authorized on it" }, {"Warning.UnableToToggleEngine", "You are unable able to toggle {0}'s quarry" }, {"Warning.NoTeamFound", "You cannot use this command since you don't have a team" }, }, this, "en"); } #endregion #region Helpers // Checks if player is an admin using a permission private bool IsAdmin(BasePlayer player) { if (permission.UserHasPermission(player.UserIDString, adminPerm)) return true; return false; } private void Message(string message, BasePlayer player, params string[] args) => SendReply(player, lang.GetMessage($"{config.chatSettings.chatPrefix} {message}", this), args); private void MessageConsole(string message, params string[] args) => PrintWarning(lang.GetMessage($"{config.chatSettings.chatPrefix} {message}", this), args); #endregion #region Commands // The command that is listed in the config void QuarryShareCommand(BasePlayer bPlayer, string command, params string[] args) { // If the player just types /qm or the length is 0 meaning if it is not /qm add or something like that then send them a help message if (args == null || args.Length == 0) { // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, usePerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } Message(lang.GetMessage("Info.Help", this, bPlayer.UserIDString), bPlayer); return; } // We don't want the player trying to toggle team share without a team (if you change the team sub command then make sure you change this) if (args.Contains("team") || args.Contains("t")) { // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, teamLockPerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } // Checks they don't have a team if (bPlayer.currentTeam == 0) { Message(lang.GetMessage("Warning.NoTeamFound", this, bPlayer.UserIDString), bPlayer); return; } } switch (args[0].ToLower()) { case "h": case "help": // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, usePerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } Message(lang.GetMessage("Info.Help", this, bPlayer.UserIDString), bPlayer); return; // If you change the team commands (t or team) make sure you change the ones on line 541 as well if you don't then it will not work as intended case "t": case "team": // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, teamLockPerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } // Checks if the player is not in the data file if (!playerData.GetPlayer(bPlayer.userID)) { playerData.AddPlayer(bPlayer.userID, false, null); SaveData(); } // Checks if the player has enabled team share if (playerData.players[bPlayer.userID].EnabledTeamShare) { if (config.chatSettings.quarryShareMessages.messageOnTeamShareEnabled) { Message(lang.GetMessage("Info.TeamSharingDisabled", this, bPlayer.UserIDString), bPlayer); } if (config.chatSettings.serverConsoleMessages.messageRCONOnEnabledTeamShare) { MessageConsole(lang.GetMessage("Info.MessageRconOnTeamShareDisabled", this, bPlayer.UserIDString), bPlayer.displayName); } playerData.players[bPlayer.userID].EnabledTeamShare = false; SaveData(); } else { // Now checks if the player has disabled team share if (config.chatSettings.quarryShareMessages.messageOnTeamShareDisabled) { Message(lang.GetMessage("Info.TeamSharingEnabled", this, bPlayer.UserIDString), bPlayer); } if (config.chatSettings.serverConsoleMessages.messageRCONOnDisableTeamShare) { MessageConsole(lang.GetMessage("Info.MessageRconOnTeamShareEnabled", this, bPlayer.UserIDString), bPlayer.displayName); } playerData.players[bPlayer.userID].EnabledTeamShare = true; SaveData(); } return; case "a": case "add": // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, playerLockPerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } // Checks if the player is not in the data file if (!playerData.GetPlayer(bPlayer.userID)) { playerData.AddPlayer(bPlayer.userID, false, null); SaveData(); } // Checks if the player is trying to add 2 players. Eg: /qm add enforcer player1 <- Arg 2 (I will probably add the ability to add multiple players) if (args.Length != 2) { Message(lang.GetMessage("Warning.UnableToFindPlayer", this, bPlayer.UserIDString), bPlayer); return; } AddOrRemoveUser(bPlayer, true, false, args); return; case "r": case "remove": // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, playerLockPerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } // Checks if the player is not in the data file if (!playerData.GetPlayer(bPlayer.userID)) { playerData.AddPlayer(bPlayer.userID, false, null); SaveData(); } // Checks if the player is trying to remove 2 players. Eg: /qm remove enforcer player1 <- Arg 2 (I will probably add the ability to remove multiple players) if (args.Length != 2) { Message(lang.GetMessage("Warning.UnableToFindPlayer", this, bPlayer.UserIDString), bPlayer); return; } AddOrRemoveUser(bPlayer, false, true, args); return; case "ra": case "removeall": // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, playerLockPerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } // Checks if the player is not in the data file if (!playerData.GetPlayer(bPlayer.userID)) { playerData.AddPlayer(bPlayer.userID, false, null); SaveData(); } // If the player added no one then just return it if (playerData.players[bPlayer.userID].addedPlayers.Count == 0) return; // Clears the concurrent players playerData.players[bPlayer.userID].addedPlayers.Clear(); addedPlayersAccess = false; Message(lang.GetMessage("Info.RemovedAllPlayers", this, bPlayer.UserIDString), bPlayer); SaveData(); return; case "l": case "list": // Checks if has permission if (!permission.UserHasPermission(bPlayer.UserIDString, playerLockPerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } // Checks if the player is not in the data file if (!playerData.GetPlayer(bPlayer.userID)) { playerData.AddPlayer(bPlayer.userID, false, null); SaveData(); } // Again checking if the player has no one added and prints a message and returns if (playerData.players[bPlayer.userID].addedPlayers.Count == 0) { Message(lang.GetMessage("Info.NoAddedPlayers", this, bPlayer.UserIDString), bPlayer); return; } // Gets all added players and print it out. Count by index and if that player meets that index value then print their name foreach (var addedPlayer in playerData.players[bPlayer.userID].addedPlayers) { addedPlayerList.Append($"{count}. {addedPlayer.Value}\n"); count++; } Message(lang.GetMessage("Info.ListCurrentPlayers", this, bPlayer.UserIDString), bPlayer, addedPlayerList.ToString()); return; // This area is to check if the player did something like /qm test. Since the sub command test does not exist then just send them to this area default: // Checks if the player has the required permission if (!permission.UserHasPermission(bPlayer.UserIDString, usePerm)) { Message(lang.GetMessage("Warning.NoPermission", this, bPlayer.UserIDString), bPlayer); return; } Message(lang.GetMessage("Info.Help", this, bPlayer.UserIDString), bPlayer); return; } } #endregion #region Hooks // Oxide hook to check if the player is able to loot the container of the quarry object CanLootEntity(BasePlayer bPlayer, ResourceExtractorFuelStorage container) { // Checks if the quarry container id is equalled to 0 or the player is an admin if (container.OwnerID == 0 || IsAdmin(bPlayer)) return null; if (container.OwnerID != bPlayer.userID) { if (!config.shareSettings.canOpenQuarryContainers) return null; if(playerData.players.ContainsKey(container.OwnerID)) { teamAccess = playerData.players[container.OwnerID].EnabledTeamShare; if (teamAccess) { if (config.shareSettings.teamSharing.canTeamOpenQuarry) { if (BasePlayer.FindAwakeOrSleeping(container.OwnerID.ToString()).currentTeam != bPlayer.currentTeam) return true; // Returning true does not allow them to loot the containers. Returning null allows them to loot the containers if (playerData.players[container.OwnerID].EnabledTeamShare) { return null; } else { Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); return true; } } } if (!addedPlayersAccess) { if (playerData.players[container.OwnerID].addedPlayers.Count == 0) { addedPlayersAccess = false; } else { addedPlayersAccess = true; } } if (addedPlayersAccess) { if (config.shareSettings.individualPlayerSharing.canAddedPlayersOpenQuarry) { if (playerData.players[container.OwnerID].addedPlayers.ContainsKey(bPlayer.userID)) { return null; } else { Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); return true; } } } } Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); return true; } return null; } private void OnQuarryToggled(MiningQuarry quarry, BasePlayer bPlayer) { // Static quarry part // Checks if the quarry is static if (quarry.isStatic) { if (!LockZone) { if (quarry.IsOn()) { // Locks the zone using an ejector component (StaticQuarry) class isStaticQuarryToggled = true; staticQuarryToggler = bPlayer.userID; LockZone = true; if (config.chatSettings.quarryShareMessages.messageOnStaticQuarryBeingUsed) { Message(lang.GetMessage("Info.StaticQuarryActivated", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); } if (config.chatSettings.serverConsoleMessages.messageRCONOnStaticQuarryBeingUsed) { MessageConsole(lang.GetMessage("Info.MessageRconOnStaticQuarryActivated", this, bPlayer.UserIDString), quarry.transform.position.ToString(), bPlayer.displayName); } return; } } } else { // Normal quarry part if (config.shareSettings.canToggleQuarry) return; if (quarry == null) return; if (quarry.OwnerID == 0 || quarry.OwnerID == bPlayer.userID || IsAdmin(bPlayer)) return; // Had to do this part since people were able to loot the quarry some how for some reason. This just gets the item and checks if it inside the quarry var item = quarry.fuelStoragePrefab.instance.GetComponent().inventory.FindItemsByItemName("lowgradefuel"); if (item == null) { Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); return; } teamAccess = playerData.players[quarry.OwnerID].EnabledTeamShare; if (teamAccess) { if (config.shareSettings.teamSharing.canTeamToggleQuarry) { // Checks if the player is inside the quarry owners team if (BasePlayer.FindAwakeOrSleeping(quarry.OwnerID.ToString()).currentTeam == bPlayer.currentTeam) { if (playerData.players[quarry.OwnerID].EnabledTeamShare) return; else { quarry.SetOn(!quarry.IsOn()); Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); } } } } if (!addedPlayersAccess) { if (playerData.players[quarry.OwnerID].addedPlayers.Count == 0) { addedPlayersAccess = false; } else { addedPlayersAccess = true; } } if (addedPlayersAccess) { if (config.shareSettings.individualPlayerSharing.canAddedPlayersToggleQuarry) { if (!playerData.players[quarry.OwnerID].addedPlayers.ContainsKey(bPlayer.userID)) { quarry.SetOn(!quarry.IsOn()); Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); } else { return; } } } quarry.SetOn(!quarry.IsOn()); // There was a bug that could drain peoples fuel when toggled and so I just plus it so it does not happen. This is for someone who tries to access it without the correct conditions met item.amount++; Message(lang.GetMessage("Warning.UnableToAccessContainer", this, bPlayer.UserIDString), bPlayer/*, config.chatsettings.chaticon*/); } } #endregion #region Functions // I will make this better and allow non caps. It is currently case sensitive public BasePlayer FindPlayer(string nameOrID) { foreach (BasePlayer player in BasePlayer.activePlayerList) { if (player.userID.ToString() == nameOrID) return player; if (player.displayName == nameOrID) return player; if (player.name.Contains(nameOrID)) return player; } return null; } // Adds or remove user private void AddOrRemoveUser(BasePlayer player, bool isAdding, bool isRemoving, string[] args) { var user = FindPlayer(args[1]); if (isAdding) { if (user.userID == player.userID) { Message(lang.GetMessage("Warning.UnableToAddSelf", this, player.UserIDString), player); return; } if (user == null) { Message(lang.GetMessage("Warning.UnableToFindPlayer", this, player.UserIDString), player, user.displayName); return; } if (playerData.players[player.userID].addedPlayers.ContainsKey(user.userID)) { Message(lang.GetMessage("Warning.AlreadyAdded", this, player.UserIDString), player, user.displayName); return; } playerData.players[player.userID].addedPlayers.Add(user.userID, user.displayName); SaveData(); if (config.chatSettings.quarryShareMessages.messageOnAddedToPlayerList) { Message(lang.GetMessage("Info.AddedPlayer", this, player.UserIDString), player, user.displayName); } if (config.chatSettings.serverConsoleMessages.messageRCONOnAddedToShareList) { MessageConsole(lang.GetMessage("Info.MessageRconOnPlayerAdded", this, player.UserIDString), player.displayName, user.displayName); } return; } if (isRemoving) { if (playerData.players[player.userID].addedPlayers.Count == 0) return; if (!playerData.players[player.userID].addedPlayers.ContainsKey(user.userID)) return; playerData.players[player.userID].addedPlayers.Remove(user.userID); SaveData(); if (config.chatSettings.quarryShareMessages.messageOnRemovedFromPlayerList) { Message(lang.GetMessage("Info.RemovedPlayer", this, player.UserIDString), player, user.displayName); } if (config.chatSettings.serverConsoleMessages.messageRCONOnRemovedToPlayerList) { MessageConsole(lang.GetMessage("Info.MessageRconOnPlayerRemoved", this, player.UserIDString), player.displayName, user.displayName); } return; } } // Random thing I made to check if the user is inside added players //private bool IsUserValid(BasePlayer player, string[] args) //{ // var user = FindPlayer(args[1]); // if (playerData.players[player.userID].addedPlayers.ContainsKey(user.userID)) // { // return true; // } // return false; //} // Gets the entity private static BaseEntity GetEntity(Collider collider) { var entity = collider.ToBaseEntity(); while (entity != null && entity.HasParent() && !(entity is BaseMountable) && !(entity is BasePlayer)) { entity = entity.GetParentEntity(); } return entity; } // Credits to ZoneManager for some of this part public static Vector3 MoveLocation(Vector3 position, float distance, Vector3 target, float radius, float yAmount) { var location = ((position.XZ3D() - target.XZ3D()).normalized * (distance + radius)) + target; var y = TerrainMeta.HighestPoint.y + 300f; RaycastHit raycast; if (Physics.Raycast(new Ray(new Vector3(0f, y, 0f), Vector3.down), out raycast, 500, layers, QueryTriggerInteraction.Ignore)) { location.y = raycast.point.y + yAmount; } else location.y = TerrainMeta.HeightMap.GetHeight(location) + yAmount; return location; } // Moves the player public static bool MovePlayer(BasePlayer bPlayer, Vector3 pos) { // Checks if the player is sleeping if (bPlayer.IsSleeping()) { return false; } // Gets the move position var movePos = MoveLocation(bPlayer.transform.position, 5f, pos, 30f, 1f); // Checks if the player is flying if (bPlayer.IsFlying) { pos.y = bPlayer.transform.position.y; } // Teleports the player bPlayer.Teleport(movePos); bPlayer.SendNetworkUpdateImmediate(); return true; } // Moves the mountable public static bool MoveMountable(BaseMountable bMountable, Vector3 pos, float distance, float radius) { BaseVehicle vehicle = bMountable as BaseVehicle; var movePos = MoveLocation(bMountable.transform.position, distance, pos, radius, 10f); // Checks if vehicle is null or destoryed if (vehicle == null || vehicle.IsDestroyed) return false; bMountable.transform.position = movePos; return true; } // A check to see if the static quarry contains fuel private static bool IsStaticQuarryContainsFuel(MiningQuarry quarry) { var fuelItem = quarry.fuelStoragePrefab.instance.GetComponent().inventory.FindItemsByItemName("lowgradefuel"); if (quarry.isStatic) { if (fuelItem == null) return false; return true; } return false; } #endregion #region Static Quarry // Finds the quarry void FindStaticQuarry(BaseNetworkable entity) { // Checks if entity is null if (entity == null) return; // Gets the component since BaseNetworkable does not have it var quarry = entity.GetComponent(); // Checks if the quarry is a quarry. Probably should just do if(quarry) instead of that. if (quarry is MiningQuarry) { // Checks if the quarry is static if (quarry.isStatic) { // Create a sphere. Will add an option in cofig to change how big it should be or if it should be enabled/disabled. CreateSphere(entity.transform.position, 60f); // Makes the collider. The reason it is 30 meters is because for some reason the collider was way out of where it should be (it was too big). StaticQuarry.Init(entity.transform.position, 30f); } } } void CreateSphere(Vector3 spherePosition, float radius) { // Create sphere var sphere = GameManager.server.CreateEntity("assets/prefabs/visualization/sphere.prefab", spherePosition, Quaternion.identity) as SphereEntity; // Check if it is null if (sphere == null) return; var sphereEntity = sphere.GetComponent(); sphereEntity.currentRadius = radius; sphereEntity.lerpSpeed = 0f; // Spawn it sphere.Spawn(); // Add it to the list sphereEntities.Add(sphere); } // Ejector component public class StaticQuarry : MonoBehaviour { private static StaticQuarry staticQuarry; private GameObject _gameObject; private float colRadius; // When creating a sphere and expecting something to happen it is not the actual sphere is it a collider. Below is how we make it // Credits to RaidableBases for Init() public static void Init(Vector3 position, float radius) { GameObject gameObject; if (staticQuarry == null) { gameObject = new GameObject(); staticQuarry = gameObject.AddComponent(); staticQuarry._gameObject = gameObject; } else { gameObject = staticQuarry._gameObject; } // Sets the position gameObject.transform.position = staticQuarry._gameObject.transform.position = position; gameObject.layer = (int) Layer.Trigger; // Add a sphere colider to it var col = gameObject.AddComponent(); // Make sure the center of the collider is zero and is in the actual center col.center = Vector3.zero; // Set the radius col.radius = staticQuarry.colRadius = radius; // Make it a trigger col.isTrigger = true; // Add the component to the static quarries list staticQuarries.Add(staticQuarry); } // Called when a player enters the collider private void OnTriggerEnter(Collider collider) { if (collider == null) return; // Gets the collider var entity = GetEntity(collider); // Checks if the entity is a player if (entity is BasePlayer) { var bP = entity as BasePlayer; if (IsBypassAllowed(bP)) { return; } if (isStaticQuarryToggled) { // If the quarry toggler does not equal the player who is trying to enter steam ID then move the player but first check if the zone is locked if (staticQuarryToggler != bP.userID) { if (LockZone) { MovePlayer(bP, staticQuarry.gameObject.transform.position); // Needed because sometimes the actual thing that we are trying to do does not happen on client bP.SendNetworkUpdateImmediate(); } } else { return; } } } // Check if entity is a mountable if (entity is BaseMountable) { var bM = entity as BaseMountable; // Get the mounted player var bPlayer = bM.GetMounted(); var mountedPlayer = new List(); // Adds the monuted player to the list above mountedPlayer.Add(bPlayer); // Checks if the player is in the list if (mountedPlayer.Contains(bPlayer)) { // Check if the zone is locked meaning able to enter and wont push the player back if (LockZone) { // Move and send an update MoveMountable(bM, staticQuarry.gameObject.transform.position, 5f, 30f); bM.SendNetworkUpdateImmediate(); } } else { return; } } } // Called when a player leaves the collider private void OnTriggerExit(Collider collider) { if (collider == null) return; // Get the collider in this case static quarry var entity = GetEntity(collider); // Checks if the entity is a player. This part is pretty straight forward. if (entity is BasePlayer) { var bP = entity as BasePlayer; if (Instance.config.shareSettings.staticQuarrySharing.localSharing.unlockStaticQuarryOnExitDome) { if (staticQuarryToggler == bP.userID) { LockZone = false; staticQuarryToggler = 0; } else { return; } } } if (entity is BaseMountable) { var bM = entity as BaseMountable; var bP = entity as BasePlayer; var bPlayer = bM.GetMounted(); var mountedPlayer = new List(); mountedPlayer.Add(bPlayer); if (bP.isMounted && entity is BaseMountable) { if (Instance.config.shareSettings.staticQuarrySharing.localSharing.unlockStaticQuarryOnExitDome) { if (!mountedPlayer.Contains(bP) && staticQuarryToggler != bP.userID) { LockZone = false; staticQuarryToggler = 0; } else { return; } } } } } // A bypass check. If those things in the return are true then allow them to bypass/go through the sphere. private bool IsBypassAllowed(BasePlayer player) { return Instance.permission.UserHasPermission(player.UserIDString, "quarrymanager.allowbypass") || player.limitNetworking; } } #endregion } }